TL;DR
- JavaScript ファイルの先頭に
// @ts-checkを書くと、TypeScript に置き換えなくても型チェックを有効にできる。 - ただしチェックはかなり緩い。最終的なゴールは TypeScript への置き換えなので、JSDoc で完璧に型を付けることに時間をかけない。
内容
@ts-check の位置づけ
TypeScript に移行するとき、JavaScript ファイルの先頭に // @ts-check を追加すると、そのファイルの型チェックを有効にできる。ただし、チェックは非常に限定的で、noImplicitAny をオフにした場合よりも緩い。最終的なゴールは TypeScript に置き換えることなので、JSDoc でコードを完璧に型付けすることに時間をかけない。
よく出るエラーと解決策
宣言されていないグローバル変数
// @ts-check
console.log(user.firstName)
// ~~~~ Cannot find name 'user'そのシンボルが別の場所で定義されているなら、型宣言ファイルに書く。
// types.d.ts
interface UserData {
firstName: string
lastName: string
}
declare let user: UserDataサードパーティのライブラリ
型宣言のパッケージ(@types/...)を別にインストールする必要がある。
npm i --save-dev @types/jqueryDOM
DOM を扱うコードでは、具体的な要素の型が分からずにエラーになることがある(項目75)。
const ageEl = document.getElementById("age")
ageEl.value = "12" // 型エラー: Property 'value' does not exist on type 'HTMLElement'JSDoc で型アサーションを書いて解決する。
const ageEl = /** @type {HTMLInputElement} */ (document.getElementById("age"))
ageEl.value = "12" // OK既存の JSDoc が誤っている
/**
* 要素のサイズを(ピクセル単位で)取得する。
* @param {Node} el 対象の要素
* @returns {{w: number, h: number}} 要素のサイズ
*/
function getSize(el) {
const bounds = el.getBoundingClientRect()
// ~~~~~~~~~~~~~~~~~~~~~ Property 'getBoundingClientRect' does not exist
// on type 'Node'
return { width: bounds.width, height: bounds.height }
// ~~~~~ Type '{ width: any; height: any }' is not
// assignable to type '{ w: number; h: number }'
}IDE の言語サービスが提供するクイックフィックスで直せる。ただし、うまくいかない場合もあり、そのときは手で直す。