首页 > 解决方案 > 打字稿中包含联合类型的对象的可区分联合

问题描述

请建议一个更好的标题,我不确定到底要问什么。

我有一个看起来像这样的类型定义:

type Animal =
  | {
    'species': 'cat'
    'action': 'meow'
  }
  | {
    'species': 'cat'
    'action': 'whine'
  }
  | {
    'species': 'dog' | 'tree'
    'action': 'bark'
  };

我想定义一个条件类型ActionsFor<S>,导致给定物种的缩小类型。例如:

type CatActions = ActionsFor<'cat'> // should be 'meow' | 'whine'
type DogActions = ActionsFor<'dog'> // should be 'bark'
type TreeActions = ActionsFor<'tree'> // should be 'bark'
type BarkActions = ActionsFor<'dog'|'tree'> // should be 'bark'

我目前的尝试很接近,但不能如我所愿地与联合物种一起工作:

type ActionFor<S extends Animal['species']> = Extract<Animal, {species: S}>['action']

结果是:

type CatActions = ActionsFor<'cat'> // correct - 'meow' | 'whine'
type DogActions = ActionsFor<'dog'> // WRONG - never
type TreeActions = ActionsFor<'tree'> // WRONG - never
type BarkActions = ActionsFor<'dog'|'tree'> // correct - 'bark'

如何重新定义 ActionsFor 来做我想做的事?

标签: typescript

解决方案


弄清楚了。这似乎可行,但如果有人可以让它更短或更优雅,我会全力以赴!

type ActionFor<S extends Animal['species']> = Exclude<Animal, {species: Exclude<Animal['species'], S>}>['action']

推荐阅读