Skip to content

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

💻 playground


js
// @ts-check
console.log(user.firstName)
//          ~~~~ Cannot find name 'user'

💻 playground


ts
interface UserData {
  firstName: string
  lastName: string
}
declare let user: UserData

💻 playground


js
// @ts-check
$('#graph').style({ width: '100px', height: '100px' })
// Error: Cannot find name '$'

💻 playground


js
// @ts-check
$('#graph').style({ width: '100px', height: '100px' })
//          ~~~~~ Property 'style' does not exist on type 'JQuery<HTMLElement>'

💻 playground


js
// @ts-check
const ageEl = document.getElementById('age')
ageEl.value = '12'
//    ~~~~~ Property 'value' does not exist on type 'HTMLElement'

💻 playground


js
// @ts-check
const ageEl = /** @type {HTMLInputElement} */ (document.getElementById('age'))
ageEl.value = '12' // OK

💻 playground


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; }'
}

💻 playground


js
// @ts-check
/**
 * @param {number} val
 */
function double(val) {
  return 2 * val
}

💻 playground


ts
function loadData(data) {
  data.files.forEach(async (file) => {
    // ...
  })
}

💻 playground


ts
/**
 * @param {{
 *  files: { forEach: (arg0: (file: any) => Promise<void>) => void; };
 * }} data
 */
function loadData(data) {
  // ...
}

💻 playground

Released under the MIT License.