最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript文件里添加JSDoc注解

    正文概述 掘金(JayYuen)   2021-08-14   580

    支持的JSDoc

    下面的列表列出了当前所支持的JSDoc注解,你可以用它们在JavaScript文件里添加类型信息。

    注意,没有在下面列出的标记(例如@async)都是还不支持的。

    • @type
    • @param (or @arg or @argument)
    • @returns (or @return)
    • @typedef
    • @callback
    • @template
    • @class (or @constructor)
    • @this
    • @extends (or @augments)
    • @enum

    它们代表的意义与usejsdoc.org上面给出的通常是一致的或者是它的超集。 下面的代码描述了它们的区别并给出了一些示例。

    @type

    可以使用@type标记并引用一个类型名称(原始类型,TypeScript里声明的类型,或在JSDoc里@typedef标记指定的) 可以使用任何TypeScript类型和大多数JSDoc类型。

    /**
     * @type {string}
     */
    var s;
    
    /** @type {Window} */
    var win;
    
    /** @type {PromiseLike<string>} */
    var promisedString;
    
    // You can specify an HTML Element with DOM properties
    /** @type {HTMLElement} */
    var myElement = document.querySelector(selector);
    element.dataset.myData = '';
    

    @type可以指定联合类型—例如,stringboolean类型的联合。

    /**
     * @type {(string | boolean)}
     */
    var sb;
    

    注意,括号是可选的。

    /**
     * @type {string | boolean}
     */
    var sb;
    

    有多种方式来指定数组类型:

    /** @type {number[]} */
    var ns;
    /** @type {Array.<number>} */
    var nds;
    /** @type {Array<number>} */
    var nas;
    

    还可以指定对象字面量类型。 例如,一个带有a(字符串)和b(数字)属性的对象,使用下面的语法:

    /** @type {{ a: string, b: number }} */
    var var9;
    

    可以使用字符串和数字索引签名来指定map-likearray-like的对象,使用标准的JSDoc语法或者TypeScript语法。

    /**
     * A map-like object that maps arbitrary `string` properties to `number`s.
     *
     * @type {Object.<string, number>}
     */
    var stringToNumber;
    
    /** @type {Object.<number, object>} */
    var arrayLike;
    

    这两个类型与TypeScript里的{ [x: string]: number }{ [x: number]: any }是等同的。编译器能识别出这两种语法。

    可以使用TypeScript或Closure语法指定函数类型。

    /** @type {function(string, boolean): number} Closure syntax */
    var sbn;
    /** @type {(s: string, b: boolean) => number} Typescript syntax */
    var sbn2;
    

    或者直接使用未指定的Function类型:

    /** @type {Function} */
    var fn7;
    /** @type {function} */
    var fn6;
    

    Closure的其它类型也可以使用:

    /**
     * @type {*} - can be 'any' type
     */
    var star;
    /**
     * @type {?} - unknown type (same as 'any')
     */
    var question;
    

    转换

    TypeScript借鉴了Closure里的转换语法。 在括号表达式前面使用@type标记,可以将一种类型转换成另一种类型

    /**
     * @type {number | string}
     */
    var numberOrString = Math.random() < 0.5 ? "hello" : 100;
    var typeAssertedNumber = /** @type {number} */ (numberOrString)
    

    导入类型

    可以使用导入类型从其它文件中导入声明。 这个语法是TypeScript特有的,与JSDoc标准不同:

    /**
     * @param p { import("./a").Pet }
     */
    function walk(p) {
        console.log(`Walking ${p.name}...`);
    }
    

    导入类型也可以使用在类型别名声明中:

    /**
     * @typedef { import("./a").Pet } Pet
     */
    
    /**
     * @type {Pet}
     */
    var myPet;
    myPet.name;
    

    导入类型可以用在从模块中得到一个值的类型。

    /**
     * @type {typeof import("./a").x }
     */
    var x = require("./a").x;
    

    @param@returns

    @param语法和@type相同,但增加了一个参数名。 使用[]可以把参数声明为可选的:

    // Parameters may be declared in a variety of syntactic forms
    /**
     * @param {string}  p1 - A string param.
     * @param {string=} p2 - An optional param (Closure syntax)
     * @param {string} [p3] - Another optional param (JSDoc syntax).
     * @param {string} [p4="test"] - An optional param with a default value
     * @return {string} This is the result
     */
    function stringsStringStrings(p1, p2, p3, p4){
      // TODO
    }
    

    函数的返回值类型也是类似的:

    /**
     * @return {PromiseLike<string>}
     */
    function ps(){}
    
    /**
     * @returns {{ a: string, b: number }} - May use '@returns' as well as '@return'
     */
    function ab(){}
    

    @typedef, @callback, 和 @param

    @typedef可以用来声明复杂类型。 和@param类似的语法。

    /**
     * @typedef {Object} SpecialType - creates a new type named 'SpecialType'
     * @property {string} prop1 - a string property of SpecialType
     * @property {number} prop2 - a number property of SpecialType
     * @property {number=} prop3 - an optional number property of SpecialType
     * @prop {number} [prop4] - an optional number property of SpecialType
     * @prop {number} [prop5=42] - an optional number property of SpecialType with default
     */
    /** @type {SpecialType} */
    var specialTypeObject;
    

    可以在第一行上使用objectObject

    /**
     * @typedef {object} SpecialType1 - creates a new type named 'SpecialType1'
     * @property {string} prop1 - a string property of SpecialType1
     * @property {number} prop2 - a number property of SpecialType1
     * @property {number=} prop3 - an optional number property of SpecialType1
     */
    /** @type {SpecialType1} */
    var specialTypeObject1;
    

    @param允许使用相似的语法。 注意,嵌套的属性名必须使用参数名做为前缀:

    /**
     * @param {Object} options - The shape is the same as SpecialType above
     * @param {string} options.prop1
     * @param {number} options.prop2
     * @param {number=} options.prop3
     * @param {number} [options.prop4]
     * @param {number} [options.prop5=42]
     */
    function special(options) {
      return (options.prop4 || 1001) + options.prop5;
    }
    

    @callback@typedef相似,但它指定函数类型而不是对象类型:

    /**
     * @callback Predicate
     * @param {string} data
     * @param {number} [index]
     * @returns {boolean}
     */
    /** @type {Predicate} */
    const ok = s => !(s.length % 2);
    

    当然,所有这些类型都可以使用TypeScript的语法@typedef在一行上声明:

    /** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */
    /** @typedef {(data: string, index?: number) => boolean} Predicate */
    

    @template

    使用@template声明泛型:

    /**
     * @template T
     * @param {T} x - A generic parameter that flows through to the return type
     * @return {T}
     */
    function id(x){ return x }
    

    用逗号或多个标记来声明多个类型参数:

    /**
     * @template T,U,V
     * @template W,X
     */
    

    还可以在参数名前指定类型约束。 只有列表的第一项类型参数会被约束:

    /**
     * @template {string} K - K must be a string or string literal
     * @template {{ serious(): string }} Seriousalizable - must have a serious method
     * @param {K} key
     * @param {Seriousalizable} object
     */
    function seriousalize(key, object) {
      // ????
    }
    

    @constructor

    编译器通过this属性的赋值来推断构造函数,但你可以让检查更严格提示更友好,你可以添加一个@constructor标记:

    /**
     * @constructor
     * @param {number} data
     */
    function C(data) {
      this.size = 0;
      this.initialize(data); // Should error, initializer expects a string
    }
    /**
     * @param {string} s
     */
    C.prototype.initialize = function (s) {
      this.size = s.length
    }
    
    var c = new C(0);
    var result = C(1); // C should only be called with new
    

    通过@constructorthis将在构造函数C里被检查,因此你在initialize方法里得到一个提示,如果你传入一个数字你还将得到一个错误提示。如果你直接调用C而不是构造它,也会得到一个错误。

    不幸的是,这意味着那些既能构造也能直接调用的构造函数不能使用@constructor

    @this

    编译器通常可以通过上下文来推断出this的类型。但你可以使用@this来明确指定它的类型:

    /**
     * @this {HTMLElement}
     * @param {*} e
     */
    function callbackForLater(e) {
        this.clientHeight = parseInt(e) // should be fine!
    }
    

    @extends

    当JavaScript类继承了一个基类,无处指定类型参数的类型。而@extends标记提供了这样一种方式:

    /**
     * @template T
     * @extends {Set<T>}
     */
    class SortableSet extends Set {
      // ...
    }
    

    注意@extends只作用于类。当前,无法实现构造函数继承类的情况。

    @enum

    @enum标记允许你创建一个对象字面量,它的成员都有确定的类型。不同于JavaScript里大多数的对象字面量,它不允许添加额外成员。

    /** @enum {number} */
    const JSDocState = {
      BeginningOfLine: 0,
      SawAsterisk: 1,
      SavingComments: 2,
    }
    

    注意@enum与TypeScript的@enum大不相同,它更加简单。然而,不同于TypeScript的枚举,@enum可以是任何类型:

    /** @enum {function(number): number} */
    const Math = {
      add1: n => n + 1,
      id: n => -n,
      sub1: n => n - 1,
    }
    

    更多示例

    var someObj = {
      /**
       * @param {string} param1 - Docs on property assignments work
       */
      x: function(param1){}
    };
    
    /**
     * As do docs on variable assignments
     * @return {Window}
     */
    let someFunc = function(){};
    
    /**
     * And class methods
     * @param {string} greeting The greeting to use
     */
    Foo.prototype.sayHi = (greeting) => console.log("Hi!");
    
    /**
     * And arrow functions expressions
     * @param {number} x - A multiplier
     */
    let myArrow = x => x * x;
    
    /**
     * Which means it works for stateless function components in JSX too
     * @param {{a: string, b: number}} test - Some param
     */
    var fc = (test) => <div>{test.a.charAt(0)}</div>;
    
    /**
     * A parameter can be a class constructor, using Closure syntax.
     *
     * @param {{new(...args: any[]): object}} C - The class to register
     */
    function registerClass(C) {}
    
    /**
     * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any')
     */
    function fn10(p1){}
    
    /**
     * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any')
     */
    function fn9(p1) {
      return p1.join();
    }
    

    已知不支持的模式

    在值空间中将对象视为类型是不可以的,除非对象创建了类型,如构造函数。

    function aNormalFunction() {
    
    }
    /**
     * @type {aNormalFunction}
     */
    var wrong;
    /**
     * Use 'typeof' instead:
     * @type {typeof aNormalFunction}
     */
    var right;
    

    对象字面量属性上的=后缀不能指定这个属性是可选的:

    /**
     * @type {{ a: string, b: number= }}
     */
    var wrong;
    /**
     * Use postfix question on the property name instead:
     * @type {{ a: string, b?: number }}
     */
    var right;
    

    Nullable类型只在启用了strictNullChecks检查时才启作用:

    /**
     * @type {?number}
     * With strictNullChecks: true -- number | null
     * With strictNullChecks: off  -- number
     */
    var nullable;
    

    Non-nullable类型没有意义,以其原类型对待:

    /**
     * @type {!number}
     * Just has type number
     */
    var normal;
    

    不同于JSDoc类型系统,TypeScript只允许将类型标记为包不包含null。 没有明确的Non-nullable -- 如果启用了strictNullChecks,那么number是非null的。 如果没有启用,那么number是可以为null的。


    下载网 » JavaScript文件里添加JSDoc注解

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元