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

如何基于对象值动态创建TypeScript类型?

问题:基于设计令牌对象动态生成TypeScript颜色类型

我有一个包含所有设计令牌的对象,如下所示:

const Tokens = {
  neutralColor: {
    dark: {
      '100': '#123456',
      '200': '#223456',
    },
    medium: {
      '100': '#654321',
      '200': '#876543',
    },
    light: {
      '100': '#009988',
      '200': '#334411',
    }
  },
  feedbackColor: {
    // 结构和neutralColor类似
  },
  // 其他颜色分组
}

我需要限制组件的color属性仅接受令牌中的值,比如:

<Typography color={Tokens.neutralColor.dark["100"]}>label</Typography>

// 或者直接写对应字符串
<Typography color="#123456">label</Typography>
// 因为Tokens.neutralColor.dark["100"]的值就是#123456

常规做法是手动创建联合类型:

type Color = "#123456" | "#223456" | "#654321" | /* 其他所有颜色值 */

type TypographyProps = {
  color: Color
}

function Typography(props: TypographyProps) { /* ... */ }

请问是否可以基于该令牌对象动态创建这个TypeScript类型?


解答

完全可以实现,核心是利用TypeScript的const断言和递归类型工具来自动提取所有颜色值:

步骤1:用as const锁定令牌的字面量类型

首先要确保TypeScript能精准推断出每个颜色的具体字符串值,而不是宽泛的string类型,所以需要给令牌对象加上as const断言:

const Tokens = {
  neutralColor: {
    dark: {
      '100': '#123456',
      '200': '#223456',
    },
    medium: {
      '100': '#654321',
      '200': '#876543',
    },
    light: {
      '100': '#009988',
      '200': '#334411',
    }
  },
  feedbackColor: {
    success: '#00ff00',
    error: '#ff0000'
  }
} as const;

步骤2:创建递归类型提取所有颜色值

编写一个递归的类型工具,遍历令牌对象的所有嵌套层级,收集所有字符串类型的颜色值:

// 递归提取所有嵌套的字符串值
type ExtractColorValues<T> = T extends string 
  ? T 
  : T extends object 
    ? { [K in keyof T]: ExtractColorValues<T[K]> }[keyof T] 
    : never;

// 基于Tokens生成Color类型
type Color = ExtractColorValues<typeof Tokens>;

此时Color类型会自动生成为所有颜色值的联合类型,等价于:

type Color = "#123456" | "#223456" | "#654321" | "#876543" | "#009988" | "#334411" | "#00ff00" | "#ff0000";

步骤3:在组件Props中使用该类型

直接把生成的Color类型应用到组件属性上即可:

type TypographyProps = {
  color: Color;
};

function Typography(props: TypographyProps) {
  return <span style={{ color: props.color }}>{props.children}</span>;
}

这样就能实现需求:既可以传入令牌对象的属性值,也可以直接写对应的颜色字符串,同时TypeScript会自动校验值是否在令牌范围内。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 17:50:30