2017-04-03 72 views
1

什么导致此代码失败?Typescript中的接口上的类级通用约束

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

回答

2

如果你会怎么做:

let data: ISomeData = new SomeData(); 

你不会得到这个错误,但T不是ISomeData,这是什么“更”比ISomeData,例如,它可以是:

interface IMoreData extends ISomeData { 
    username: string; 
} 

然后你说:

let data: IMoreData = new SomeData(); 

这是不正确的,因为它缺少username财产。
,你可以告诉你知道你在做什么(AKA铸造)编译器解决这个问题:

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

或者只是:

let data = new SomeData() as T; 
+0

谢谢,原来如此!我有点想这就是我需要做的,不知道为什么我不试试它! –

+0

就像一个侧面问题,不是约束,指出“你的实现必须是[THIS]的最小值”(在我的情况下'接口ISomeData {名称:字符串}'),并没有实现该接口,以确保它有“名称:字符串”?我仍然不明白为什么它不会在这里隐含地理解我的意图。这是通过设计,还是像语言规范中的“待办事项”? :)不过,你摇滚,谢谢! –

+1

是的,通用约束保证'name'存在于'T'中,但**'T' **不是**'ISomeData',所以编译器会警告你。如果你有一个'SomeClass '的实例,那么'initSomeData'的结果应该是'IMoreData'类型而不是'ISomeData' –