将类型参数混合到类的实例类型中

时间:2018-08-24 22:13:44

标签: typescript class

有没有一种方法可以基于其属性创建具有动态索引结构的类?

我一直在努力解决这个问题,我能够使用type来进行索引签名,但是我只能实现一个接口。在类/接口中是否有与此不同的语法?或者只是不可能?

interface BaseAttributes {
    id: string;
}

class One<A extends BaseAttributes> {
    //1023: An index signature parameter type must be 'string' or 'number'.
    [key: keyof A]: A[key];

    constructor(attr: A) {
        for(const key in attr) {
            this[key] = attr[key]; // I want to type this
        }
    }
}

interface TwoAttributes extends BaseAttributes{
    label: string;
}

class Two extends One<TwoAttributes> {
}

1 个答案:

答案 0 :(得分:0)

我花了几分钟时间弄乱了它,找不到任何方法来定义其实例类型包含所需类型变量的类;请参阅this issue comment。请注意,即使该问题已标记为已解决,并且其标题似乎描述了您想要的内容,AFAICT标题实际上也指的是基本构造函数为类型参数(这是mixin类所允许的),而不是包含类型参数的实例类型

我最接近的是编写无类型的One类,然后将其强制转换为通用构造函数,以便可以使用为A指定的任何具体类型来扩展它:

interface BaseAttributes {
    id: string;
}

class OneUntyped {
  constructor(attr: {}) { 
    Object.assign(this, attr);
  }
}
const One = OneUntyped as {new<A extends BaseAttributes>(attr: A): OneUntyped & A};

interface TwoAttributes extends BaseAttributes{
    label: string;
}

class Two extends One<TwoAttributes> {
}

let two: Two;
console.log(two.label);

// Error: Base constructor return type 'OneUntyped & A' is not a class or interface type.
class Three<A extends BaseAttributes> extends One<A> { }