はじめに
TypescriptのHandbookのInterfaces Extending Classesを写経していたとき、次のコードをtsc main.ts
でコンパイルしようとしたところエラーが発生。
class Control {
private state: any;
}
interface SelectableControl extends Control {
select(): void;
}
class Button extends Control implements SelectableControl {
select() { }
}
class TextBox extends Control {
}
// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
select() { }
}
class Location {
}
対策
以下のようにtsc
のlib
オプションをes5
やes6
にすることで解決。
tsc --lib es5 main.ts
何が起きているのか
コンパイル時のエラーは次の通り。
$ tsc main.ts
../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts(11522,11): error TS2300: Duplicate identifier 'Location'.
../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts(11538,13): error TS2300: Duplicate identifier 'Location'.
../../.config/yarn/global/node_modules/typescript/lib/lib.d.ts(18989,13): error TS2300: Duplicate identifier 'Image'.
main.ts(18,7): error TS2300: Duplicate identifier 'Image'.
main.ts(18,7): error TS2420: Class 'Image' incorrectly implements interface 'SelectableControl'.
Property 'state' is missing in type 'Image'.
main.ts(22,7): error TS2300: Duplicate identifier 'Location'.
下から2つ目のエラーはImage
クラスがSelectableControl
インターフェースを実装できていないということで予想通りのエラーだが、他のエラーは「LocationやImageが既に宣言されている」という内容になっている。
どうやらtsc
はデフォルトでnode_modules/typescript/lib/lib.d.ts
を読みに行っているらしい。対応する行を確認すると確かに宣言されていた。
// 18989行目
declare var Image: { new(width?: number, height?: number): HTMLImageElement; };
// 11522行目
interface Location {
....
}
公式ドキュメントによるとtsc
はデフォルトで--lib es5,dom,scripthost
で走るようで、domに関する宣言ファイルを読み込んでいるため上のようなエラーが出てしまっているようだ。 1
まとめ
ドキュメントをしっかり読んでデフォルトオプションには気をつけたいところだ。
-
正確には
--target
がES5
の場合に--lib
がes5,dom,scripthost
になります。デフォルトの--target
はES3
なので、--target
がES5
の場合と同じ挙動なのかわかりませんが、dom
はES3の場合にも含まれているようです。 ↩