Javascript TypeScript:映射强类型集合

Javascript TypeScript:映射强类型集合,javascript,typescript,Javascript,Typescript,我有一个强类型集合,如下所示: 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: 'Mi

我有一个强类型集合,如下所示:

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
。好吧,问题是它为什么会这样?)

接口定义了对象必须具有的一些属性,但它并不是详尽无遗的;对象还可以具有其他属性。文档中演示了这一点。

它之所以有效,是因为定义了接口的属性。该接口不阻止添加其他属性

然而:

const nextUsers: IUser[] = users.map((user: IUser) => ({
  ID: 3, // wrong field name
  name: 'Mike',
}));

这会导致TypeScript编译器出现错误。

它仍然可以工作,但如果您有TypeScript linter,则会出现错误,因为返回的数组类型不同,因此IUse[]

这是TypeScript检查多余属性的副产品。一点背景:

如果类型B至少具有类型A的所有属性,则类型A通常可从类型B进行赋值。因此,例如,执行此赋值时,预计不会出现错误:

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' }
现在,在您的情况下,typescript将首先推断结果的类型,将其映射到返回的对象文本的类型,该类型都是有效的,然后将检查该类型是否与它所在的
IUser
数组兼容,因此没有错误,因为我们从未直接尝试将对象文本分配给类型为
IUser
的对象

如果显式设置传递给
map

const nextUsers: IUser[] = users.map((user: IUser) : IUser => ({
    id: 3,
    name: 'Mike',
    ID: 152,
}));

我更新了你的问题,以反映游乐场链接中的实际代码。您的原始代码将无法工作这实际上是由于一个错误:谢谢!很好的提示和箭头函数的类型!