TL;DR (結論を3行で)
- TypeScript では型
T?
は許容されていない (2023年10月現在) - JSDoc では
T?
と書ける -
.d.ts
ファイルではT?
は許容されていないが、skipLibCheck: true
にすると許容される
なんか書いてみたら通ってしまった
TypeScript で .d.ts
ファイルには型定義を書くことができ、たとえば以下のようになります。
declare interface Hoge {
myNum?: number;
myStr?: string;
}
しかし、ある日うっかり以下のようなコードを書いてしまいました。
declare interface Hoge {
myNum: number?;
myStr: string?;
}
後日このコードは誤りであることが分かったものの、vscode でも tsc でもエラーは出ていませんでした。なぜなのでしょうか?
skipLibCheck を false にするとエラーが出る
tsconfig.json
に skipLibCheck: false
を設定するとエラーが出てきて、それが原因だったことが分かりました。
skipLibCheckの挙動
true を設定することで *.d.ts ファイルに対する型チェックをスキップすることができます。
{
"compilerOptions": {
- "skipLibCheck": true,
+ "skipLibCheck": false,
...
}
}
src/sample.d.ts:2:10 - error TS8020: JSDoc types can only be used inside documentation comments.
2 myNum: number?;
~~~~~~~
src/sample.d.ts:3:10 - error TS8020: JSDoc types can only be used inside documentation comments.
3 myStr: string?;
~~~~~~~
これは JSDoc で使われる型定義の書き方で、TypeScript ではこのように書くことはできないそうです。
JSDoc では T? と書ける(らしい)
エラーメッセージによると JSDoc というライブラリでは Nullable types を T?
のように書くことができるそうですが、JSDoc のリファレンスには ?T
のように ? を前置する書き方しか記載されておらず、T?
というように ? を後置する書き方についての公式的な記載は見つけられませんでした。
Nullable types only have meaning if strictNullChecks is on:
/** * @type {?number} * With strictNullChecks: true -- number | null * With strictNullChecks: false -- number */ var nullable;
が、どうやら書けるようです。
- ?T, T?
- 前置と後置に意味的な違いはない。
- strictNullChecksが無効の場合は ? は無視され、中身 T がそのまま使われる。
vscode では一応 T | null
に解釈される
TypeScript で T?
が T | null
または T | undefined
または T | null | undefined
のいずれに解釈されるべきなのかという話については色々な意見がありますが、試してみたところ、一応 vscode 上では T | null
と解釈されるようです。(any
にはならない)
(property) Hoge.myNum: number | null
(参考:一方で optional property は T | undefined
と解釈されます。)