繁体   English   中英

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

[英]Typescript - conditional types based on value in a for of list

所以这些是我的类型:

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”语句的左侧不能使用类型注释。

您可以使用in类型保护来区分具有不相等键的对象类型的联合:

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

游乐场链接

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


或者,您可以创建自定义类型保护来区分这两种类型。 这涉及一个函数,该函数接受您的联合类型并在运行时评估该值是否为特定类型。 您可以使用类型断言访问联合中的非共享字段:

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

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

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

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

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

const list: Array<Result> = [{A: 'foo', B: 'bar'}, {A: 'foo', C: 'baz'}]
for (const item of list) {
  // Run code from other answers here
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM