Item 80: Use @ts-check and JSDoc to Experiment with TypeScript
要点
- Add "
// @ts-check
" to the top of a JavaScript file to enable type checking without converting to TypeScript. - Recognize common errors. Know how to declare globals and add type declarations for third-party libraries.
- Use JSDoc annotations for type assertions and better type inference.
- Don't spend too much time getting your code perfectly typed with JSDoc. Remember that the goal is to convert to .ts!
- 在 JavaScript 文件顶部添加 "
// @ts-check
" 以启用类型检查,而无需转换为 TypeScript。 - 识别常见错误。了解如何声明全局变量并为第三方库添加类型声明。
- 使用 JSDoc 注释进行类型断言和更好的类型推断。
- 不要花太多时间通过 JSDoc 让代码完美类型化。记住,目标是转换为 .ts 文件!
正文
js
// @ts-check
const person = { first: 'Grace', last: 'Hopper' }
2 * person.first
// ~~~~~~~~~~~~ The right-hand side of an arithmetic operation must be of type
// 'any', 'number', 'bigint' or an enum type
js
// @ts-check
console.log(user.firstName)
// ~~~~ Cannot find name 'user'
ts
interface UserData {
firstName: string
lastName: string
}
declare let user: UserData
js
// @ts-check
$('#graph').style({ width: '100px', height: '100px' })
// Error: Cannot find name '$'
js
// @ts-check
$('#graph').style({ width: '100px', height: '100px' })
// ~~~~~ Property 'style' does not exist on type 'JQuery<HTMLElement>'
js
// @ts-check
const ageEl = document.getElementById('age')
ageEl.value = '12'
// ~~~~~ Property 'value' does not exist on type 'HTMLElement'
js
// @ts-check
const ageEl = /** @type {HTMLInputElement} */ (document.getElementById('age'))
ageEl.value = '12' // OK
js
// @ts-check
/**
* Gets the size (in pixels) of an element.
* @param {Node} el The element
* @return {{w: number, h: number}} The size
*/
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; }'
}
js
// @ts-check
/**
* @param {number} val
*/
function double(val) {
return 2 * val
}
ts
function loadData(data) {
data.files.forEach(async (file) => {
// ...
})
}
ts
/**
* @param {{
* files: { forEach: (arg0: (file: any) => Promise<void>) => void; };
* }} data
*/
function loadData(data) {
// ...
}