Just do IT

思うは招く

TypeScript async function の型をどう書くか

async関数のreturn typeにvoidを定義した。

const someFunc = async (): void => {
    await someMethod()
}

TypeScriptに叱られる。

Type 'void' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value

こう書く。

const someFunc = async (): Promise<void> => {
    await someMethod()
}

stringやオブジェクトを返したいなら。

const someFunc = async (): Promise<string> => {
    await someMethod()
}


type Props = { ~ }
const someFunc = async (): Promise<Props> => {
    await someMethod()
}

CommonJSとESModulesの違い

結論

  • CommonJSとESModulesは、どちらもJavaScriptでモジュールシステムを扱うときの仕様
  • Node.jsはCommonJSしかサポートしていなかったが、今ではESModulesもサポートしている
  • 2022年現在ではESModulesを使うことが多い

JavaScriptのモジュールシステムとは

JavaScriptの関数や変数をファイルで分割する仕組み。現在のJavaScript(TypeScript)開発では主流となっている。保守性や可読性が向上し、開発しやすくなる。ようするに1つのモジュールは1つのJavaScript(TypeScript)ファイル。

CommonJS

  • 2009年にMozillaのエンジニアにより開始されたプロジェクト
  • 基本はNode.js(サーバーサイド)での仕様
  • NodeプロジェクトはデフォルトだとCommonJS仕様になっている
  • 外部モジュールを使うときにはrequireを使う
  • モジュールをexportするときはmodule.exports = 〜を使う
  • 今ではNode.jsもESModulesをサポートしている

試しにNodeプロジェクトを作ってみる。

npm init -y

showName.jsというファイルを作り、以下を記述する。

function showName(name) {
  console.log(name)
}

export default showName

main.jsimportする。

import showName from './showName.js'

showName('test name')

これでnode main.jsを叩いてみると、、、

❯ node main.js
(node:29622) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

import showName from './showName'
^^^^^^

ESModulesでモジュールシステムを使いたいならpackage.jsonに設定してくださいね」と指摘されて動かない。なぜかというと、Node.jsはデフォルトではCommonJSで動くようになっているため。

CommonJSでいきたいなら、以下のようにmodule.exportsrequireを使う必要がある。

module.exports = showName
const showName = require('./showName.js')

ESModulesを使いたいなら、package.jsontypeとしてmoduleを指定する。これでESModulesが使えるようになる。

{
  ~
  ~
  "type": "module"
}

以下のように成功する。

❯ node main.js
test name

ESModules

  • 基本はブラウザでのモジュールシステム
    • ブラウザはCommonJSをサポートしない
  • 現在主流のJavaScriptモジュールシステム
  • 外部モジュールを使うときにはimportを使う
  • モジュールをexportするときはexport defaultexportを使う
export default function Hoge () { ~ }
import Hoge form './~'

みたいに使う。主流すぎるので説明は省略する。

参考