在定义为联合类型的属性上调用.map()

时间:2019-06-19 07:08:16

标签: arrays typescript

我有一个键入为

的对象
interface Asset {
  id: string;
}

interface Project {
  assets: Array<string> | Array<Asset>;
}

现在,如果我运行以下命令:

const project: Project = {
  assets: [
    {id: '1'}.
    {id: '2'},
    {id: '3'},
    {id: '4'}
  ],
};
project.assets.map((asset: Asset) => asset.id);

我收到此错误

  

无法调用类型缺少调用签名的表达式。类型'(((callbackfn:(值:字符串,索引:数字,数组:字符串[])=> U,thisArg ?:任何)=> U [])| ((callbackfn:(值:资产,索引:数字,数组:Asset [])=> U,thisArg ?: any)=> U [])'没有兼容的呼叫签名。

即使我将回调更改为

,该错误仍然存​​在
project.assets.map((asset: Asset | string) => {console.log(asset)});

为什么会发生这种情况,我该如何解决?

3 个答案:

答案 0 :(得分:1)

这是因为TS无法确定project.assets数组的最终类型是什么。您可以使用类型断言调用这种map函数,它将起作用:

(project.assets as Asset[]).map((asset: Asset) => asset.id)

它也不会让您断言其类型为number[],因为TS仍会检查您的断言是否与类型定义相匹配。

答案 1 :(得分:0)

您可以将Project的界面更改为:

interface Project {
  assets: Array<string|Asset>;
}

interface Project<T> {
  assets: Array<T>;
}

const project: Project<Asset> = {
  assets: [
    {id: '1'}.
    {id: '2'},
    {id: '3'},
    {id: '4'}
  ],
};
project.assets.map((asset: Asset) => asset.id);

答案 2 :(得分:0)

不确定没有泛型是否有可能,但至少可以正常工作。

interface Project<T extends string | Asset> {
    assets: Array<T>;
}
const project: Project<Asset> = {
    assets: [
        {id: '1'},
        {id: '2'},
        {id: '3'},
        {id: '4'}
    ],
};
project.assets.map((asset) => {})