有没有办法指定数组包含父类和子类项

时间:2017-06-22 09:48:09

标签: typescript

假设我有以下层次结构:

interface Cmp {
  guid: string;
}

interface ContainerCmp extends Cmp {
  layout: string;
}

现在,我有一系列可以是CmpContainerCmp类型的项目。这意味着数组中的某些项将缺少layout属性。

现在打字稿并不允许我为items指定两种类型:

const items: Cmp[] | ContainerCmp[] = [];
items.forEach((item) => {
  if (isContainerCmp(item)) {
    console.log(item.layout);
  }
});

产生错误:

Error:(28, 1) TS2349:Cannot invoke an expression whose type lacks a call signature. 
Type '{ (callbackfn: (this: void, value: Cmp, index: number, array: Cmp[]) => void): void; 
(callbackfn:...' has no compatible call signatures.

所以我指定最顶级Cmp类型并使用类型保护:

const items: Cmp[] = [];
items.forEach((item) => {
  if (isContainerCmp(item)) {
    console.log(item.layout);
  }
});

function isContainerCmp(cmp: Cmp | ContainerCmp): cmp is ContainerCmp {
  return (<ContainerCmp>cmp).layout !== undefined;
}

我想知道它是否是正确的方法,是否有其他任何方式为数组items指定两种类型?

1 个答案:

答案 0 :(得分:1)

这是一个只有Cmp或仅ContainerCmp的数组。

const items: Cmp[] | ContainerCmp[] = [];

这是一个同时包含CmpContainerCmp的数组。

const items: (Cmp | ContainerCmp)[] = [];
// or
const items: Array<Cmp | ContainerCmp> = [];

编辑:在答案中添加了@NitzanTomer建议。