繁体   English   中英

typescript 从子 class 调用的构造函数参数推断类型

[英]typescript infer type from constructor argument called by sub class

我有一个 class 具有一些属性/方法,这些属性/方法返回最初通过构造函数传递的值:

class Base {
  constructor(arg) {
     this.options = arg.options;
  }
}

人们建议使用 class 和 generics 作为 typescript 等效项:

class Base<T extends {options: any}> {
    options: T["options"];

    constructor(arg: T) {
        this.options = arg.options;
    }    
}

// works fine with instantiation
const inst = new Base({options: {foo: 123}});
inst.options.foo++; // ok
inst.options.bar; // TS Error

现在我有一个子 class 调用超类的构造函数并传递这些选项:

class Sub extends Base { // TS Error
    constructor() {
        super({options: {foo: 123}});
        this.options.foo++; // TS Error
    }
}

Typescript 编译器对此不满意,并希望通过该类型扩展 Base class。 但后来我有两次信息,在超级调用和扩展符号中。 解决我的问题的正确 ts 语法是什么?

(代码在typescript 操场上)

编辑:

问题不在于super()而在于extends Base 无论如何, typescript 必须推断出 Base 的泛型类型,您不能指望 typescript 从对super()的调用中推断出这一点。


起初我会建议这样做

    class Sub<T extends {options: any}> extends Base<T> {
    constructor() {
        super({options: {foo: 123}})
    }}

但这不起作用,因为不允许将具体实例分配给类型参数 如果我们改为这样做,它会起作用

    class Sub<T extends {options: any}> extends Base<T> {
    constructor(arg: T) {
        super(arg)
    }}

const inst2 = new Sub({options: {foo: 123}})
inst2.options.foo++; // ok   

我认为正确的解决方案是简单地这样做

    class Sub extends Base<{options: any}> {
    constructor() {
        super({options: {foo: 123}})
    }}

但是,仍然存在问题。

const inst2 = new Sub();
inst2.options.foo++; //options is any which makes sense, we said that options is any above

你知道我们为什么使用 generics 吗? 当我们事先不知道类型是什么时。 由于在这种情况下我们确切地知道类型是什么,所以我们可以安全地这样做:

class Sub extends Base<{ options: {foo: number} }> {
    // or even class Sub extends Base<{ options: {foo: 123} }> {
    constructor() {
        super({options: {foo: 123}});
        this.options.foo++;
    }
}

const inst2 = new Sub();
inst2.options.foo++;

这样做可以吗? 当然,如果我们将选项以外的东西传递给Base ,它会触发警告。 所以我们满足Base的要求,同时确保我们传递给super()的内容与我们所说的泛型类型一致。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM