将对象数组映射到打字稿中具有不同对象的另一个数组

时间:2019-01-24 17:12:32

标签: typescript

如果我有类似的东西

array1: string[] = ['foo', 'bar'];

和类似

的界面
export interface MyObject { name: string; }

如何将array1映射到另一个MyObject类型的数组?

array2 : MyObject[];
array2 = array1.map(s => ...);

我想到了类似的东西

array2 = array1.map<MyObject>(s => new MyObject(...));

2 个答案:

答案 0 :(得分:2)

通常这是我讨论long lecture的类型和TypeScript值之间的区别的地方,但是在这里我会尽量简短:因为MyObject仅被称为< em> type 而不是构造函数 value ,您不能调用new MyObject()。相反,如果要创建类型为MyObject的值,则可以仅使用普通的旧对象of the right shape,例如通过object literal notation

const myObject: MyObject = {name: "Alice"}; // no error

因此您的map函数可以是:

const array2: MyObject[] = array1.map(s => ({name: s})); // no error

简单,对吧?

嗯,好吧,请注意上面的注释,{name: s}的括号是necessary,因为JavaScript解析器将(x => {...})形式的箭头函数解释为好坏是具有block body,其中花括号内的内容为语句。而且,当您将name: s解释为语句时,这意味着namelabel,而s只是一个字符串expression statement optional semicolon omitted。解释为函数体,{name: s}仅求值s,并且不返回定义的值(它是void,与undefined基本上相同),它是如果省略括号,为什么会出现以下奇怪错误:

let array2: MyObject[] = array1.map(s => { name: s }); // error!
// Type 'void[]' is not assignable to type 'MyObject[]'.
// at runtime, array2 will be [undefined, undefined] which is not what you wanted 

JavaScript的解析有点棘手。添加括号使s => (...)可以解决该问题。现在,箭头后面的内容只能解释为concise body ...,即单个表达式。并将({name: s})解释为表达式会产生我们想要的对象文字。

是的,我避免写一本关于类型和值的书,以某种方式最终写了一本关于表达式和语句的书。哦,很好。

希望对您有帮助。祝你好运!

答案 1 :(得分:1)

您不能将MyObject用作构造函数,因为它是interface而不是class。因此,这里的一个选项是您可以将array1属性映射为MyObject属性,然后使用MyObject[]将类型更改为as数组

const array1: string[] = ['foo', 'bar'];

export interface MyObject { name: string; }

let array2 : MyObject[];

array2 = array1.map(v => { return {name: v}; }) as MyObject[];

或其他选项,您还可以创建MyObject类,该类将实现IMyObject接口,并且可以调用构造函数。这是一个示例

const array1: string[] = ['foo', 'bar'];

export interface IMyObject { name: string; }

class MyObject implements IMyObject {
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

let array2 : IMyObject[];

array2 = array1.map(v => new MyObject(v)) as IMyObject[];