代码之家  ›  专栏  ›  技术社区  ›  rst

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

  •  0
  • rst  · 技术社区  · 5 年前

    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 回复  |  直到 5 年前
        1
  •  17
  •   jcalz    5 年前

    这通常是我偏离主题的地方 long lecture 关于TypeScript中类型和值之间的区别,但这里我将尽量简短:因为 MyObject 只知道是一个 而不是构造函数 ,你不能打电话 new MyObject() ,您可以只使用普通的旧对象 of the right shape ,例如via 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 陈述 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 => (...) concise body ... 也就是说,一个表达式。和解释 ({name: s}) 作为一个表达式,可以生成我们想要的对象文本。

    希望这对你有帮助。祝你好运

        2
  •  3
  •   Artyom Amiryan    5 年前

    你不能打电话 MyObject 作为构造函数,因为它是 interface 而不是 class . 这里有一个选项,你可以直接映射 array1 属性为 肌体 属性,然后将类型更改为 MyObject[] 排列 as

    const array1: string[] = ['foo', 'bar'];
    
    export interface MyObject { name: string; }
    
    let array2 : MyObject[];
    
    array2 = array1.map(v => { return {name: v}; }) as 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[];