为什么Array.map允许我传递非泛型类型的成员

时间:2019-02-21 10:36:44

标签: typescript

为什么在使用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;
});

1 个答案:

答案 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中了解了更多信息。