如果我有类似的东西
array1: string[] = ['foo', 'bar'];
和类似
的界面export interface MyObject { name: string; }
如何将array1映射到另一个MyObject类型的数组?
array2 : MyObject[];
array2 = array1.map(s => ...);
我想到了类似的东西
array2 = array1.map<MyObject>(s => new MyObject(...));
答案 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
解释为语句时,这意味着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})
解释为表达式会产生我们想要的对象文字。
是的,我避免写一本关于类型和值的书,以某种方式最终写了一本关于表达式和语句的书。哦,很好。
希望对您有帮助。祝你好运!
答案 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[];