【问题标题】:Class-level generic constraint on interface in TypescriptTypescript中接口的类级通用约束
【发布时间】:2017-08-28 12:47:22
【问题描述】:

是什么导致此代码失败?

interface ISomeData {
    name: string;
}

class SomeData implements ISomeData {
    name: string = "adam";
}

class SomeClass<T extends ISomeData> {
    constructor(dataTemplate?: T) {
        this.dataTemplateInternal = dataTemplate;
    }

    private dataTemplateInternal: T;

    public initSomeData() : T {
        let data: T = new SomeData();
        if (this.dataTemplateInternal) {
            return this.dataTemplateInternal;
        }
        return data;
    }
}

“initSomeData”的第一行有一个错误提示

类型“SomeData”不可分配给类型“T”

但由于我的通用约束基于 SomeData 实现的接口,这还不够吗?

Ridiculously long link to this code in the TypeScript Playground

【问题讨论】:

    标签: generics typescript


    【解决方案1】:

    如果你愿意:

    let data: ISomeData = new SomeData();
    

    您不会收到此错误,但T 不是ISomeData,它比ISomeData“更多”,例如它可以是:

    interface IMoreData extends ISomeData {
        username: string;
    }
    

    然后你说:

    let data: IMoreData = new SomeData();
    

    这是不正确的,因为它缺少 username 属性。
    你可以通过告诉编译器你知道你在做什么(AKA cast)来解决这个问题:

    let data: T = new SomeData() as T;
    

    或者只是:

    let data = new SomeData() as T;
    

    【讨论】:

    • 谢谢,就是这样!我有点想这就是我需要做的,不知道为什么我不尝试一下!
    • 作为一个附带问题,不是说“您的实现必须至少是 [THIS]”(在我的情况下为 interface ISomeData { name: string })并且没有实现该接口保证它有“名称:字符串”吗?我仍然不太明白为什么它没有隐含地理解我的意图。这是设计使然,还是像语言规范中的“待办事项”? :) 不过,你摇滚,谢谢!
    • 是的,通用约束确保name 存在于T但是 T ISomeData 所以编译器会警告你。如果您有SomeClass&lt;IMoreData&gt; 的实例,那么initSomeData 的结果应该是IMoreData 类型而不是ISomeData
    猜你喜欢
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2018-11-28
    • 2021-07-04
    • 1970-01-01
    相关资源
    最近更新 更多