是否可以编写索引类型,其中键是区分联合的区分属性,值是联合成员

时间:2019-12-16 15:14:51

标签: typescript

我有这样的类型:

type Cat = {sound: 'Meaow', species: 'cat'}
type Dog = {sound: 'Woff', species: 'dog'}

type Animal = Cat | Dog

我想为物种编写一个“注册表”,以强制每个物种与其区分键相关联:

所以,类似这样的东西(TS不允许这种语法)

type RegisteredAnimals<T extends Animal> = { [key: T['species'] ]?: T}

1 个答案:

答案 0 :(得分:2)

// types allow only on Animal with given spec
type WithTheSpecies<T extends Animal, Spec extends Animal['species']> = 
T extends { species: Spec } ? T : never;
// mapped type which has key as spec, and value only type with exactly that spec
type RegisteredAnimals<T extends Animal = Animal> = 
{ [K in T['species']]?: WithTheSpecies<T, K> }

// using
const reg: RegisteredAnimals = {
  cat: { sound: 'Meaow', species: 'cat' },
  dog: { sound: 'Woff', species: 'dog' },
}

说明

我们需要映射类型,该类型将确保我们仅使用种类键K in T['species'],但也需要确保给定键处的值是具有该种类值的对象。第一种类型在此处为RegisteredAnimals,第二种类型为WithTheSpecies