typescript JSDoc performs type checking on js files

(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

Guess you like

Origin blog.csdn.net/weixin_43294560/article/details/114295751