这不应该编译,但确实如此:
var thingsWithName: { name: string }[] = [{ 'name': 'A' }, { 'name': 'B' }];
function doStuff <T extends { id: number }> (thingWithId: T): T {
return thingWithId;
}
thingsWithName.map(doStuff);
正如您所看到的那样thingsWithName
没有id
,因此在将doStuff
传递给地图时,打字稿编译器会发出警告。
为什么这个类型检查?我做错了吗?
答案 0 :(得分:1)
请参阅ICU Formatting Dates and Times。
团队概述的原因是:
我们的可分配性关系忽略了签名中的泛型和约束。它只是用any替换所有类型参数。
...我们忽略了泛型,因为我们认为将它们考虑在内会很慢。一般来说,如果签名是泛型类型,它会导致永无止境的递归。因此,似乎不值得。
在您的代码中,请注意非通用版本会引发错误:
function doStuff(thingWithId: { id: number }): { id: number } {
return thingWithId;
}
thingsWithName.map(doStuff); // error
另外请注意,由于typescript使用结构类型来检查类型,因此非泛型版本将发生以下情况:
var arrayWithId = [{ id: 2, myOtherProperty: "other value" }],
arrayWithoutId = [{ noIdProperty: 2 }];
arrayWithId.map(doStuff); // ok
arrayWithoutId.map(doStuff); // error