【问题标题】:Map array of object to another array with different object in typescript将对象数组映射到打字稿中具有不同对象的另一个数组
【发布时间】:2019-06-18 12:11:39
【问题描述】:

如果我有类似的东西

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

还有一个类似的界面

export interface MyObject { name: string; }

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

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

我想过类似的事情

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

【问题讨论】:

  • 只有当有一个名为 MyObject 的构造函数 value 生成 type MyObject 的实例时才有效。由于MyObject 只是一个接口,您可以通过object literal 来创建一个接口,例如{name: s}。这是作业还是什么?只是想知道我们应该在这里提供多少帮助。
  • 不是作业,我从供应商(公司)处购买的 Angular 应用程序的代码改进
  • 那么array1.map(s =&gt; ({name: s})) 应该适合你。 (编辑:用括号括起来的表达式,因为 js 在这里错误地解释了s =&gt; {...})
  • 不,不是,编译器说void is not assignable to type,但这显然在这里工作map(s =&gt; ({name: s}))
  • 我的编辑没有及时给你,哦,好吧

标签: typescript


【解决方案1】:

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

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[];

【讨论】:

    【解决方案2】:

    这通常是我离题到 long lecture 关于 TypeScript 中类型和值之间的差异的地方,但在这里我会尽量简短:因为 MyObject 只知道是一个 类型 而不是构造函数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
    

    简单吧?

    呃,好吧,请注意,在上面的 cmets 中,{name: s} 周围的括号是 necessary,因为无论好坏,JavaScript 解析器都会将 (x =&gt; {...}) 形式的箭头函数解释为具有 block body,其中花括号内的东西是语句。当您将name: s 解释为语句 时,这意味着name 是label,而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 =&gt; (...) 修复它。现在箭头后面的东西只能解释为concise body...,也就是单个表达式。并将({name: s}) 解释为表达式会产生我们想要的对象字面量。

    是的,我避免写一本关于类型和值的书,并且不知何故最终写了一本关于表达式和语句的不同书。哦,好吧。

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

    【讨论】:

      猜你喜欢
      • 2020-08-06
      • 2018-05-31
      • 2019-02-13
      • 1970-01-01
      • 2023-03-15
      • 2022-11-24
      • 2022-12-19
      • 2021-07-07
      • 1970-01-01
      相关资源
      最近更新 更多