(1)修改tsconfig.js
"checkJs": true, 对js文件进行类型检查
你可以通过添加// @ts-nocheck注释来忽略类型检查;
相反,你可以通过去掉--checkJs设置并添加一个// @ts-check注释来选则检查某些.js文件。
你还可以使用// @ts-ignore来忽略本行的错误。
如果你使用了tsconfig.json,JS检查将遵照一些严格检查标记,如noImplicitAny,strictNullChecks等。 但因为JS检查是相对宽松的,在使用严格标记时可能会有些出乎意料的情况。
(2)使用
1、@type
可以使用@type标记并引用一个类型名称(原始类型,TypeScript里声明的类型,或在JSDoc里@typedef标记指定的)可以使用任何TypeScript类型和大多数JSDoc类型。
方式一:在变量上方使用
普通变量
/**
* @type {string}
*/
var s;
/** @type {Window} */
/** @type {PromiseLike<string>} */
/** @type {HTMLElement} */
/** @type {*} */ 不能是any类型
/** @type {?} */ 是any类型
联合类型:
/** @type {string | boolean} */
数组:
/** @type {number[]} */
/** @type {Array.<number>} */
/** @type {Array<number>} */
字符串和数字索引签名来指定对象,或者使用ts索引签名形式
/** @type {Object.<string, number>} */ 约束键值对类型
/** @type {{[index:string]:number}} */
函数
/** @type {(s: string, b: boolean) => number} */
方式二:在括号前使用
var typeAssertedNumber = /** @type {string} */ (2)
2、@param
定义导入语法
/** @param { import("./a").Pet } */
let x=只能是导入的Pet类型
/** @type {typeof import("./a").x } */ 从模块中得到一个值的类型。
定义可变参数
/** @param {...string} p1 */
定义函数参数
/**
* @param {string} p1 定义p1类型
* @param {string=} p2 定义可选参数 (Closure syntax)
* @param {string} [p3] 定义可选参数 (JSDoc syntax).
* @param {string} [p4="test"] 定义可选参数和默认值
* @return {string} 定义返回值类型
*/
function stringsStringStrings(p1, p2, p3, p4){
return '2'
}
定义函数参数高级属性
/**
* @param {Object} options 可以使用object或Object,定义一个叫options的高级属性
* @param {string} options.prop1 options内的属性prop1及类型
* @param {number} options.prop2 options内的属性prop2及类型
* @param {number=} options.prop3 options内的可选属性
* @param {number} [options.prop4] options内的可选属性
* @param {number} [options.prop5=42] options内的可选属性和默认值
*/
3、@return
定义返回值类型
/** @return {string} */
4、@typeof
定义别名或高级类型,能在type中使用
定义别名:
/** typeof {类型} 别名 */
定义高级类型
/**
* @typedef {Object} SpecialType 可以使用object或Object,创建一个叫SpecialType的高级类型
* @property {string} prop1 SpecialType类型的prop1参数及其类型
* @property {number} prop2 SpecialType类型的prop2参数及其类型
* @property {number=} prop3 SpecialType类型的可选参数及类型
* @prop {number} [prop4] SpecialType类型的可选参数及类型,@prop和@property等级
* @prop {number} [prop5=42] SpecialType类型的可选参数及类型和默认值
*/
/** @type {SpecialType} */
var specialTypeObject={prop1:'2',prop2:2};
替换成@typeof写法:
/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */
5、@callback
@callback与@typedef相似,但它指定函数类型而不是对象类型:
/**
* @callback Predicate
* @param {string} data 定义第一个参数类型
* @param {number} [index] 定义第二个参数可选
* @returns {boolean} 定义返回值
*/
/** @type {Predicate} */
const ok = s => {return true};
替换成@typeof写法:
/** @typedef {(data: string, index?: number) => boolean} Predicate */
6、@template
使用@template声明泛型
/**
* @template T 泛型可声明多个
* @param {T} x 传递到返回类型的泛型参数
* @return {T}
*/
function id(x){ return x }
限制泛型类型
/**
* @template {类型} T 泛型可声明多个
* @param {T} x 传递到返回类型的泛型参数
* @return {T}
*/
7、@constructor
编译器通过this属性的赋值来推断构造函数,但你可以让检查更严格提示更友好,你可以添加一个@constructor标记:
/**
* @constructor
* @param {number} data
*/
function C(data) {
this.size = 0;
this.initialize(data); 报错,传入的参数应该为string类型,而非number
}
/**
* @param {string} s
*/
C.prototype.initialize = function (s) {
this.size = s.length
}
var c = new C(0);
var result = C(1); 必须添加new关键字,不加@constructor不会报错
this将在构造函数C里被检查,因此你在initialize方法里得到一个提示,如果你传入一个数字你还将得到一个错误提示。如果你直接调用C而不是构造它,也会得到一个错误,不幸的是
这意味着那些既能构造也能直接调用的构造函数不能使用@constructor。
8、@this
编译器通常可以通过上下文来推断出this的类型,但你可以使用@this来明确指定它的类型:
/**
* @this {HTMLElement}
* @param {*} e
*/
function callbackForLater(e) {
this.clientHeight = parseInt(e) // should be fine!
}
9、@extends
当JavaScript类继承了一个基类,无处指定其类型参数的类型,而@extends标记提供了这样一种方式:
/**
* @template T
* @extends {Set<T>}
*/
class SortableSet extends Set {
// ...
}
10、@enum
@enum标记允许你创建一个对象字面量,它的成员都有确定的类型
/** @enum {number|string} */
const JSDocState = {
BeginningOfLine: 0,
SawAsterisk: 1,
SavingComments: 2,
D:'2'
}
类中示例(js中使用函数方式的类,ES2015以前,也满足如下推断)
(1)会根据构造函数中赋的值的类型,若没在构造函数中赋值或赋值为null/undefined,则为所有赋的值的类型的联合类型
class C {
constructor() {
this.constructorOnly = 0
this.constructorUnknown = undefined
}
method() {
this.constructorOnly = false // error, constructorOnly is a number
this.constructorUnknown = "plunkbat" // ok, constructorUnknown is string | undefined
this.methodOnly = 'ok' // ok, but y could also be undefined
}
method2() {
this.methodOnly = true // also, ok, y's type is string | boolean | undefined
}
}
(2)类的属性只是读取用的,那么就在构造函数里用JSDoc声明它的类型,甚至不用赋值
class C {
constructor() {
/** @type {number | undefined} */
this.prop = undefined;
/** @type {number | undefined} */
this.count;
}
}
let c = new C();
c.prop = 0; // OK
c.count = "string"; // Error: string is not assignable to number|undefined