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

如何从对象类型派生TypeScript区分联合类型?

问题

假设我们有如下对象:

const originalObj = { foo: 'fooVal', bar: 'barVal' };

我需要编写一个工具类型,从该原始对象生成区分联合类型,联合的每个成员结构如下:

type Sample1 = {
  header: string;
  accessor: 'foo'; // 判别式
  render?: (value: 'fooVal', original: typeof originalObj) => React.ReactNode;
};

type Sample2 = {
  header: string;
  accessor: 'bar'; // 判别式
  render?: (value: 'barVal', original: typeof originalObj) => React.ReactNode;
};

手动编写的目标类型是:

type OriginalObjMappedToUnionOfSamples = Sample1 | Sample2;

现在需要实现一个工具类型GetDiscriminatedUnionOfSamples,仅给定原始对象类型时自动生成上述联合类型,达到如下效果:

type WhatIWant = GetDiscriminatedUnionOfSamples<typeof originalObj>;
解决方案

可以通过TypeScript的映射类型和索引访问类型实现这个工具类型,核心是遍历原始对象的所有键,为每个键生成对应结构后自动合并为联合类型。

实现代码如下:

import type { ReactNode } from 'react';

type GetDiscriminatedUnionOfSamples<T extends object> = {
  [K in keyof T]: {
    header: string;
    accessor: K;
    render?: (value: T[K], original: T) => ReactNode;
  };
}[keyof T];

代码说明

  1. 遍历键生成结构:{ [K in keyof T]: ... } 会遍历原始类型T的所有键K,为每个键生成一个包含header、accessor和可选render的对象类型。
  2. 类型绑定:accessor的类型直接绑定为当前键的字面量类型(比如'foo'),render函数的value参数类型绑定为原始对象中该键对应的值类型(比如'fooVal'),original参数则绑定为整个原始对象的类型。
  3. 转为联合类型:通过[keyof T]索引访问映射后的对象类型,TypeScript会自动将所有单成员结构合并成一个联合类型。

验证效果

用题目中的originalObj测试:

const originalObj = { foo: 'fooVal', bar: 'barVal' };
type WhatIWant = GetDiscriminatedUnionOfSamples<typeof originalObj>;

此时WhatIWant的类型等价于手动编写的Sample1 | Sample2,完全符合需求。

内容的提问来源于stack exchange,提问作者Abe Caymo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:45:23