首页 > 解决方案 > 将对象数组映射到打字稿中具有不同对象的另一个数组

问题描述

如果我有类似的东西

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

和一个类似的界面

export interface MyObject { name: string; }

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

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

我想到了类似的东西

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

标签: typescript

解决方案


这通常是我离题的地方,关于 TypeScript 中类型和值之间的区别的长篇演讲,但在这里我会尽量简短:因为MyObject只知道是类型而不是构造函数,所以你不能调用new MyObject(). 相反,如果你想创建一个 type 的值MyObject,你可以使用正确形状的普通旧对象,例如通过对象文字表示法

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

所以你的map功能可以如下:

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

很简单,对吧?

嗯,好吧,请注意上面的注释中的括号{name: s}必要的,因为无论好坏,JavaScript 解析器都将表单的箭头函数解释(x => {...})为具有块体,其中大括号内的内容是语句。当您解释name: s语句时,它意味着它name是一个标签,并且s只是一个省略了可选分号的字符串表达式语句。解释为函数体,只计算而不返回定义的值(它是,本质上与{name: s}svoidundefined),这就是为什么如果省略括号会出现以下奇怪错误的原因:

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 => (...)修复。现在箭头后面的东西只能解释为简洁的正文……也就是单一的表达式。解释({name: s})为表达式会产生我们想要的对象字面量。

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

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


推荐阅读