为什么在使用Array.map<T>
时可以映射T
上不存在的属性?
我在strict: true
中使用tsconfig.json
interface MappedItem {
foo: number;
}
const arr = [1, 2, 3];
// I would expect this to error, but it does not
arr.map<MappedItem>(n => ({ foo: n, bar: n }));
arr.map(n => {
// This errors as expected
// Object literal may only specify known properties, and 'bar' does not exist in type 'MappedItem'
const item: MappedItem = { foo: n, bar: n };
return item;
});
答案 0 :(得分:3)
使用时
arr.map<MappedItem>(n => ({ foo: n, bar: n }));
类型变量用于表示要返回的内容,在这种情况下为MappedItem[]
。
* 在检查对象是否为某种类型时,编译器仅检查至少存在所需的属性(等)并与所需的类型匹配。
很显然,您返回的对象满足MappedItem
的要求:具有类型foo
的属性number
。因此,当它看起来像MappedItem
时,它就是MappedItem
(这被称为鸭子打字)。
但是当您使用
const item: MappedItem = { foo: n, bar: n };
然后情况就不同了,因为* 对象文字在分配给其他变量或将它们作为参数传递时会受到特殊对待并经过过多的属性检查,因为 TypeScript采取以下立场:该代码中可能有一个错误。
因此,您看到的错误是一种特殊情况,一种安全措施。
您可以使用类型断言来解决它,例如:
const item: MappedItem = { foo: n, bar: n } as MappedItem;
您在* handbook中了解了更多信息。