打字稿-基于列表for中的值的条件类型

时间:2020-10-08 20:18:14

标签: javascript reactjs typescript

这些是我的类型:

export type typeOne = {
  A: string;
  B: string;
};

export type typeTwo = {
  A: string;
  C: string;
};

export type Result = typeOne | typeTwo; //condition 

这是用例:

for (const item: Result of list) {
   const something = item.B ? 'B exsist' : item.C;
   return something;
}

它不断返回错误:

TS2339:类型“结果”上不存在属性“ B”。类型'typeTwo'上不存在属性'B'。

,另外一个:

TS2339:类型“结果”上不存在属性“ C”。类型'typeOne'不存在属性'C'。

您知道如何解决此问题吗?

注意:循环还会发生以下错误:

TS2483:“ for ... of”语句的左侧不能使用类型注释。

3 个答案:

答案 0 :(得分:4)

您可以使用an in type guard来区分键类型不相同的对象类型的并集:

for (const item: Result of list) {
   const something = "B" in item ? 'B exsist' : item.C;
   return something;
}

Playground link

答案 1 :(得分:2)

TypeScript的细微差别之一是,如果您具有对象的并集类型,则只能访问它们之间公共的字段。通常使用此技术添加可以区分两者的公共字段。例如:

export type typeOne = {
  type: 'one';
  A: string;
  B: string;
};

export type typeTwo = {
  type: 'two'
  A: string;
  C: string;
};

export type Result = typeOne | typeTwo; //condition 

for (const item: Result of list) {
   const something = item.type === 'one' ? 'B exists' : item.C;
   return something;
}

在这种情况下,type充当区分符。在此处阅读更多信息:https://basarat.gitbook.io/typescript/type-system/discriminated-unions


或者,您可以创建一个自定义type guard来区分这两种类型。这涉及一个采用您的并集类型并在运行时评估的函数(如果值是特定类型)。您可以使用类型断言来访问联合中的非共享字段:

function isTypeOne(result: Result): result is typeOne {
  return (result as typeOne).B !== undefined;
}

for (const item: Result of list) {
   const something = isTypeOne(item) ? 'B exists' : item.C;
   return something;
}

在这里,如果isTypeOne失败,则可以从typeOne中安全地删除Result,因此类型被推断为typeTwo

答案 2 :(得分:0)

关于您提到的最后一个错误:

“ TS2483:'for ... of'语句的左侧不能使用类型注释。“

<a>类型定义应该是Result声明的一部分。这样,无需指定语句的左侧为list

例如,假设Result是一个数组:

list