我有一个强类型的集合,如下:
interface IUser {
id: number,
name: string
}
const users: IUser[] = [
{ id: 1, name: 'Bob' },
// ...
];
然后,我使用map
函数创建一个新集合:
const nextUsers: IUser[] = users.map((user: IUser) => ({
ID: 3, // wrong field name
name: 'Mike',
id: 3,
}));
如您所见,存在一个名称错误的字段-ID
。好吧,问题是为什么它work?))
答案 0 :(得分:4)
这是打字稿检查多余属性的方式的副产品。一点背景:
如果类型B至少具有类型A的所有属性,则通常可以从类型B分配类型A。因此,例如,执行此分配时不会出现错误:
let someObject = { id: 3, name: 'Mike', lastName: 'Bob' }
let user: { id: number, name: string } = someObject // Ok since someobject has all the properties of user
let userWithPass : { id: number, name: string, pass: string } = someObject // Error since someobject does not have pass
Typescript唯一会抱怨多余属性的时间是当我们尝试直接将对象常量分配给具有已知类型的某个对象时:
// Error excess property lastName
let user: { id: number, name: string } = { id: 3, name: 'Mike', lastName: 'Bob' }
现在,在您的情况下,打字稿将首先将结果的类型推断为map
到返回的对象文字的类型,这些都是有效的,然后将检查此类型是否与{{ 1}}数组,所以没有错误,因为我们从未直接尝试将对象常量分配给类型IUser
的对象。
如果我们明确设置传递给IUser
的arrow函数的返回类型,我们可以确保得到一个错误。
map
答案 1 :(得分:1)
一个接口定义了一个对象必须必须具有的一些属性,但是并不详尽。该对象也可以具有其他属性。 here文档对此进行了演示。
答案 2 :(得分:1)
它有效,因为定义了接口的属性。该界面不会阻止添加其他属性。
但是:
const nextUsers: IUser[] = users.map((user: IUser) => ({
ID: 3, // wrong field name
name: 'Mike',
}));
这会导致TypeScript编译器出错。
答案 3 :(得分:0)
它仍然可以正常工作,但是如果您有一个打字机短绒,则将出现错误,因为返回的数组类型不同于IUse []