Typescript 类型“缩小”;“一级深”;打字机中的判别并集

Typescript 类型“缩小”;“一级深”;打字机中的判别并集,typescript,Typescript,我无法对以下内容进行打字检查: type Apple = { variety: {type: 'fuji'} | {type: 'gala'} } type FujiApple = { [P in keyof Apple]: P extends 'variety' ? Extract<Apple['variety'], {type: 'fuji'}> : Apple[P] } function fujiFn(fugi: FujiApple) {} fun

我无法对以下内容进行打字检查:

type Apple = {
  variety: {type: 'fuji'} | {type: 'gala'}
}

type FujiApple = {
  [P in keyof Apple]: P extends 'variety'
    ? Extract<Apple['variety'], {type: 'fuji'}>
    : Apple[P]
}

function fujiFn(fugi: FujiApple) {}

function appleFn(apple: Apple) {
  if (apple.variety.type === 'fuji') {

    // FAILS: Argument of type 'Apple' is not assignable to parameter of type
    // 'FujiApple'
    fujiFn(apple)
  }
}

您可以使用typeguards:

function isFujiApple(arg: Apple): arg is FujiApple {
  return arg.variety.type === 'fuji';
}

function appleFn(apple: Apple) {
  if (isFujiApple(apple)) {
    fujiFn(apple); // Now it works
  }
}

我认为TS中存在一个问题,因为它无法推断联合的嵌套属性

以下是解决方案:


类型Fuji={type:'Fuji'}
类型Gala={type:'Gala'}
品种类型=富士|嘎拉
苹果类型={
品种:品种
}
富士苹果类型={
[P in keyof Apple]:P扩展了“多样性”
摘录
:苹果[P]
}
函数fujiFn(fugi:FujiApple){}
函数appleFn(苹果:变种){
如果(apple.type==='fuji'){
fujiFn({品种:苹果})//好的
}
}

typeguards很有前途,但它们不能很好地扩展到切换语句。我认为这与我在“我不喜欢的解决方案”中描述的解决方案在精神上是一样的,它有效地从被识别的部分重建FujiApple对象。我希望有一个更干净的解决方案。@user2771609请看这里我认为没有更干净的解决方案谢谢,这是一个非常有用的链接!我真的认为你应该坚持使用typeguards,这样会更安全,而且没有人会告诉你你在代码审查方面做错了,就像我们在4.2中可能看到的那样!
function isFujiApple(arg: Apple): arg is FujiApple {
  return arg.variety.type === 'fuji';
}

function appleFn(apple: Apple) {
  if (isFujiApple(apple)) {
    fujiFn(apple); // Now it works
  }
}