联合对象数组迭代的正确类型保护

correct typeguard for union object array iteration

type A = ~~;
type B = ~~;
type C = ~~;

function isA(a: string) a is A{
   return a in A
}

我有三个类型或枚举,我想迭代 U 的数组以创建另一个数组。

const arr1 = A|B|C[] // array that item's type is A|B|C
const arr2 = arr1.map(item=>{
   if(isA(item)){
     return {a: 1};
   }
   if(isB(item)){
      return {b:1};
   }
   if(isC(item)){
      return {c:1}
   }
}

IDE 推断映射值 itemA|B|C 正确

问题是当我使用 if 状态进行类型保护时,结果数组项类型包含 'undefined' 类型。

arr2 = ({a:1}|{b:1}|{c:1}|undefined)[]//like this

无论如何我可以提示项目不包含未定义值的打字稿??

你有这样一种情况,其中谓词 returns undefined(当 item 不是 A、B 或 C 时):

const arr2 = arr1.map(item=>{
   if(isA(item)){
     return {a: 1};
   }
   if(isB(item)){
      return {b:1};
   }
   if(isC(item)){
      return {c:1}
   }
}

TS 认为它可能 return 未定义。要断言它不应该,您可以抛出一个错误:

const arr2 = arr1.map(item=>{
   if(isA(item)){
     return {a: 1};
   }
   if(isB(item)){
      return {b:1};
   }
   if(isC(item)){
      return {c:1}
   }
   throw new Error("Why did this happen?");
}

现在 return 类型是 A | B | C | never,简化为 A | B | C