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

如何为主题色对象定义元组首尾元素唯一的TypeScript类型?

TypeScript 主题色类型约束:确保元组元素唯一性

需求背景

现有主题色对象定义如下:

themeColors = {
  primary: ['#fff', '#000'],
  secondary: ['#DDD', '#333'],
  error: ['#CCC', '#444']
}

当前基础类型为:

themeColor: Record<string, [string, string]>

需要给这个类型添加严格约束:所有元组的第一个元素必须唯一,第二个元素也必须唯一。以下两种情况应触发类型检查错误:

错误示例1:第一个元素重复

themeColors = {
  primary: ['#fff', '#000'],
  secondary: ['#fff', '#333'],
}

(#fff作为元组第一个元素重复出现)

错误示例2:第二个元素重复

themeColors = {
  primary: ['#fff', '#000'],
  secondary: ['#DDD', '#000']
}

(#000作为元组第二个元素重复出现)

实现方案

我们可以通过TypeScript的条件类型、递归类型和映射类型来实现这一约束,核心思路是提取所有元组的对应元素并检查唯一性:

1. 定义工具类型:提取元组元素

首先定义两个工具类型,分别提取主题色对象中所有元组的第一个和第二个元素:

// 提取所有元组的第一个元素组成元组类型
type TupleFirsts<T extends Record<string, [string, string]>> = { [K in keyof T]: T[K][0] }[keyof T][]
// 提取所有元组的第二个元素组成元组类型
type TupleSeconds<T extends Record<string, [string, string]>> = { [K in keyof T]: T[K][1] }[keyof T][]

2. 定义工具类型:检查数组元素唯一性

通过递归方式检查数组中的元素是否唯一,如果存在重复元素则返回never:

type IsUniqueArray<T extends readonly any[]> = T extends [infer First, ...infer Rest]
  ? First extends Rest[number]
    ? never
    : IsUniqueArray<Rest>
  : T

3. 定义最终主题色类型

将上述工具类型组合,约束主题色对象的两个元组元素集合都必须唯一:

type ThemeColor<T extends Record<string, [string, string]>> = 
  IsUniqueArray<TupleFirsts<T>> extends never 
    ? never 
    : IsUniqueArray<TupleSeconds<T>> extends never 
      ? never 
      : T

4. 使用示例

// 合法:所有元组元素均唯一
const validTheme: ThemeColor<{
  primary: ['#fff', '#000'],
  secondary: ['#DDD', '#333'],
  error: ['#CCC', '#444']
}> = {
  primary: ['#fff', '#000'],
  secondary: ['#DDD', '#333'],
  error: ['#CCC', '#444']
}

// 不合法:第一个元素重复,触发类型错误
const invalidTheme1: ThemeColor<{
  primary: ['#fff', '#000'],
  secondary: ['#fff', '#333'],
}> = {
  primary: ['#fff', '#000'],
  secondary: ['#fff', '#333'],
}

// 不合法:第二个元素重复,触发类型错误
const invalidTheme2: ThemeColor<{
  primary: ['#fff', '#000'],
  secondary: ['#DDD', '#000']
}> = {
  primary: ['#fff', '#000'],
  secondary: ['#DDD', '#000']
}

实现说明

  • TupleFirsts和TupleSeconds通过映射类型遍历主题色对象的所有键,提取对应元组的指定元素并组成新的元组类型;
  • IsUniqueArray递归检查数组中的每个元素,如果当前元素存在于剩余元素中,就返回never标记为不合法;
  • ThemeColor类型会分别检查两个元素集合的唯一性,只要有一个集合存在重复,就返回never,从而触发TypeScript的类型检查错误。

内容的提问来源于stack exchange,提问作者Михаил Бобрышев

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:41:32