如何为JSDoc的@this标签指定顶层对象foo的类型?
问题与解决方案
问题描述
我有一个带JSDoc属性注解的对象:
const foo = { /** @type {string[]} */ bar: [], baz: { /** * @param {string} x * @returns {number} * @this {????} */ bing(x) { this.bar.push(x); return 42; } } }; // 方法调用方式如下: var method = "bing"; foo.baz[method].call(foo, "blah");
我需要在@this标签中填入内容(替代????),以表明this参数始终是顶层对象foo。尝试过两种方式但都存在问题:
- 使用
infer foo时,IntelliSense对foo的推断结果为:
但方法内部的const foo: { bar: string[]; baz: { bing(this: foo, x: string): number; }; }this.bar类型被推断为any。 - 使用
typeof foo时,IntelliSense会将foo和this.bar都推断为any,情况更糟。
请问应该使用哪种TypeScript构造?
解决方案
要解决这个类型推断问题,你需要提前通过JSDoc的@typedef定义foo的完整类型结构,再在@this标签中引用该类型,同时给foo变量本身标注对应的类型。具体实现如下:
步骤1:定义类型别名
先用@typedef声明Foo类型,完整描述对象的结构,包括方法的this约束:
/** * @typedef {Object} Foo * @property {string[]} bar * @property {{ bing: (this: Foo, x: string) => number }} baz */
步骤2:标注变量与方法的this类型
给foo变量添加@type {Foo}注解,同时在bing方法的@this标签中引用Foo类型:
/** @type {Foo} */ const foo = { bar: [], baz: { /** * @param {string} x * @returns {number} * @this {Foo} */ bing(x) { this.bar.push(x); // 此时this.bar会被正确推断为string[] return 42; } } };
这样处理后,IntelliSense就能正确识别this指向的Foo类型,this.bar的类型会被准确推断为string[],同时foo变量的整体类型也能被正确解析。
简化写法
由于@typedef已经定义了所有属性的类型,你可以省略对象内部bar的单独@type注解,让@type {Foo}自动应用到所有属性上,进一步简化代码:
/** * @typedef {Object} Foo * @property {string[]} bar * @property {{ bing: (this: Foo, x: string) => number }} baz */ /** @type {Foo} */ const foo = { bar: [], baz: { /** * @param {string} x * @returns {number} * @this {Foo} */ bing(x) { this.bar.push(x); return 42; } } };
内容的提问来源于stack exchange,提问作者dragoncoder047
相关产品推荐
相关产品推荐

