TypeScriptのstrictルールについて、忘れがちなのでまとめる。

strictルールとは

TypeScriptの厳格化オプションのこと。

tsconfig.jsonに指定することで利用可能。

tscコマンドで作成したtsconfig.jsonには初期値としてstrictがtrue(有効)で指定されている。

tsconfig.json{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
  }
}

strictをtrue指定することで以下の設定が有効となる。

オプション 概要
noImplicitAny 暗黙のanyをエラーとする
noImplicitThis thisの型注釈を必須にする
alwaysStrict 厳密モードで解析する
strictBindCallApply bind、call、applyの型チェックをする
strictNullChecks 厳密なnullチェックをする
strictFunctionTypes 厳密な関数の型チェックをする
strictPropertyInitialization クラスプロパティの初期化を必須にする

各種Strictルールについて

noImplicitAny

有効にして以下のコードをビルドすると失敗する。

export const test = (arg) => {
    return arg;
}
// =>  Parameter 'arg' implicitly has an 'any' type.

以下のように明示的にany型を付与することでビルドが成功する。

export const test = (arg: any) => {
    return arg;
}

alwaysStrict

JavaScriptのStrictモードを有効にするための'use strict';構文を付与する。

const test = (arg) => {
    return arg;
}

出力後のJavaScriptファイルを確認すると先頭に'use strict';が付与されている。

"use strict";
var test = function (arg) {
    return arg;
};

Strictモードは推奨されているのでalwaysStrictは有効にすべき。

strictBindCallApply

BindとCallとApplyの型チェックを厳しくしてくれる。

const test = (arg: string) => {
    return arg;
}
test.call(undefined, 11); // 第2引数は存在しない
// => Argument of type 'number' is not assignable to parameter of type 'string'.

strictNullChecks

非null型へのnullと非undefined型へのundefinedの代入をエラーとする。

export const test = (arg) => {
    const hoge: string = null; // => Type 'null' is not assignable to type 'string'.
    const huga: number = undefined; // => Type 'undefined' is not assignable to type 'number'. 
    return arg;
}

strictFunctionTypes

関数の引数の共変をエラーとする。

let test = (arg: string, num: number) => {
    console.log(arg);
}

test = (arg: string) => { // 共変
    console.log(arg);
}
// => Type '(arg: string) => void' is not assignable to type '(arg: string, num: number) => void'.

strictPropertyInitialization

クラスのフィールドのプロパティを初期化していない場合エラーとする。

strictPropertyInitializationを有効にする場合strictNullChecksも有効にする必要がある。

class Test {
    private hoge: string;
}
// => Property 'hoge' has no initializer and is not definitely assigned in the constructor.

まとめ

  • TypeScriptのstrictオプションはそれほど厳しいものでもないので基本的には有効にするべきと感じた。
  • 今後のバージョンアップでオプションが追加または削除される可能性があるので、strictオプションではなく個別にオプションを有効にすべき。