如何使用Object.assign(this,{foo,bar})并使VSCode Intellisense自动完成this.foo?

4
我有一个类,大致长这样:

class MyClass {
  constructor({foo,bar}) {
    Object.assign(this,{foo,bar})
  }
}

我希望输入 this.f 时,VSCode 自动补全为 this.foo。我知道要实现此功能,需要进行以下操作:
class MyClass {
  constructor({foo,bar}) {
    this.foo = foo
    this.bar = bar
  }
}

这将会给我我想要的,但是我更愿意使用 Object.assign()。我在找到正确的JSDoc或者其他内容方面遇到了麻烦。在类的顶部添加 @prop {String} foo 或其他内容并没有任何作用。

2个回答

7

从VS Code 1.18版本开始,我们不支持Object.assign(this)的智能感知功能。此bug正在此处被跟踪。


太棒了,感谢提供链接!我会订阅那个问题。除了Object.assign()之外,您是否知道使用JSDoc的任何方法来获取智能感知以自动完成当前未被智能感知识别的任意类属性? - Ricky Kazuo Miller
1
目前还没有一个很好的故事。我们还不支持@property,这将是最佳解决方案。 - Matt Bierner
谢谢,这个消息很好。我也会订阅那个问题。 - Ricky Kazuo Miller

0

由于VSC在底层使用TypeScript提供智能感知,因此有一个带有一些权衡的解决方法:如果您不介意一些重复,则可以使用@thisJSDoc标签

您必须将类型定义为构造函数类型和分配对象类型的交集,以便为构造函数和/或要为其添加额外this智能感知的类上定义的任何字段:

/**
 * @typedef {{
 *   foo: string;
 *   bar: string;
 * }} MyAdditions
 */

class MyClass {
    /**
     * @param {MyAdditions} options
     * @this {MyClass & MyAdditions}
     */
    constructor({ foo, bar }) {
        Object.assign(this, { foo, bar });

        // all ok
        this.foo;
        this.bar;
    }

    /**
     * @this {MyClass & MyAdditions}
     */
    doSomethingWithMyAdditions() {
        const { foo, bar } = this; // all ok too
        console.log(`${foo}${bar}`);
    }
}

然而,问题在于引用类实例的属性。不幸的是,覆盖构造函数中的 this 类型并不能改变其返回类型(如上面的示例,返回类型仍为 MyClass),因此这仍然是非法的:

const c = new MyClass({ foo: "bar", bar: "foo" });
c.foo; //Property 'foo' does not exist on type 'MyClass'
c.bar; //Property 'bar' does not exist on type 'MyClass'

一个聪明到尝试在构造函数中添加@returns标签的Cookie将会遇到TS1903错误 "Type annotation cannot appear on a constructor declaration"。使用@type注释(例如@type {new() => MyClass & MyAdditions})作为一种替代方案只会导致无操作。

话虽如此,您仍可以使用@type注释(注意括号周围的new)转换实例类型(毕竟,实例化不应该经常发生):

const d = /** @type {MyClass & MyAdditions} */ (new MyClass({ foo: "bar", bar: "foo" }));
d.foo; // ok now
d.bar; // ok now

游乐场

无论如何,这只是一个解决方法,原始问题仍在待办事项列表中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接