首页 > 解决方案 > 创建映射类型时引用索引类型?

问题描述

我有一个场景,我有一个不同类型的联合,它们都有相似的签名。我想创建一个映射类型,以便可以通过 id 查找所有类型:

type Apple = {
    name: "apple", 
    value: 1, 
}; 

type Banana = {
    name: "banana", 
    value: "foobar"
}; 

type Cherry = {
    name: "cherry", 
    value: () => "hi"
}; 

type AllTypes = Apple | Banana | Cherry; 

type AllTypeKeys = AllTypes['name']; 


type TypeMap = {
    "apple": Apple; 
    "banana": Banana; 
    "cherry": Cherry; 
}

我可以手动完成,就像我在 TypeMap 中所做的那样。

但是,我更愿意做这样的事情:

type TypeMap = {
   [F['name'] in AllTypes]: F; 
}

这显然是行不通的。有没有类似的东西?

标签: typescript

解决方案


从 TypeScript 4.1 开始,您可以使用Key Remapping viaas

type TypeMap2 = {
  [K in AllTypes as K['name']]: K
}

操场


在 TypeScript 4.1 之前,您可以使用Extract

type TypeMap = {
  [V in AllTypes['name']]: Extract<AllTypes, { name: V }>
}

操场


更通用的类型可以定义为

type MapByKey<T, U extends keyof T > = {
  [K in T as K[U] & (string | number | symbol)]: K
}


// or prior to TS 4.1
type MapByKey<T, U extends keyof T > = {
  [V in T[U] & (string | number | symbol)]: Extract<T, Record<U, V>>
}

type TypeMap3 = MapByKey<AllTypes, 'name'>

操场


推荐阅读