You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript:如何从单键对象联合类型创建映射类型?

需求与问题

假设有如下联合类型定义:

type UpdateUnion =
    {foo:number} |
    {bar:string} |
    {baz: {value1: number, value2: string}};

想要构造出对应的映射类型:

type UpdateFunctions = {
    foo: (value: number) => void,
    bar: (value: string) => void,
    baz: (value: {value1: number, value2:string}) => void
};

尝试了以下代码,但仅在联合类型只有一个成员时有效,否则报错Type 'Key' cannot be used to index type 'UpdateUnion':

type KeysOfUnion<T> = T extends T ? keyof T : never;
type UpdateFunctions = {
    [Key in KeysOfUnion<UpdateUnion>]: (value: UpdateUnion[Key]) => void
}
解决方案

问题出在UpdateUnion[Key]这一步:因为UpdateUnion是联合类型,当Key是多个键的联合时,TypeScript没法直接确定每个键对应的具体类型。

可以用TypeScript 4.1+支持的映射类型重命名(as子句)来解决,直接遍历联合类型的每个成员,而不是先提取所有键的联合:

type UpdateUnion =
    {foo:number} |
    {bar:string} |
    {baz: {value1: number, value2: string}};

type UpdateFunctions = {
    [T in UpdateUnion as keyof T]: (value: T[keyof T]) => void
};

原理说明

  • [T in UpdateUnion as keyof T]:遍历联合类型UpdateUnion的每个成员T,把T的键作为映射类型的属性名。
  • T[keyof T]:获取当前成员T对应键的类型,这样每个属性对应的函数参数类型就完全匹配了。

如果需要兼容更早版本的TypeScript,也可以用条件类型提取键值对后再构造:

// 先把联合类型的每个成员转换成 {key: 键名, value: 键值类型} 的形式
type KeyValuePair<T> = T extends { [K in keyof T]: infer V } ? { key: K, value: V } : never;

type UpdateFunctions = {
    // 遍历所有键名
    [K in KeyValuePair<UpdateUnion>['key']]: 
        // 提取对应键的value类型
        (value: Extract<KeyValuePair<UpdateUnion>, { key: K }>['value']) => void
};

两种方式都能得到目标的UpdateFunctions类型,第一种更简洁直观。

内容的提问来源于stack exchange,提问作者Salvo Miosi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:35:16