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

TypeScript:如何同时约束对象值类型与推导实际键类型

问题描述

我定义了如下颜色对象:

const colorNamesToRgb: ColorNamesToRgb = {
    red: 'rgb(255, 0, 0)',
    green: 'rgb(0, 255, 0)',
    blue: 'rgb(0, 0, 255)',
    yellow: 'rgb(255, 255, 0)',
};

以及对应的类型(要求所有值均为Rgb类型):

type Rgb = `rgb(${number},${number},${number})`
type ColorNamesToRgb = {
    [key: string]: Rgb
}

但目前存在问题:colorNamesToRgb的键允许为任意字符串。我编写了如下示例函数:

type ColorName = keyof typeof colorNamesToRgb
// 可接受任意字符串,无代码补全
const getRgbByName = (colorName: ColorName) => {
    return colorNamesToRgb.colorName
}

请问是否存在一种方案,既能确保对象所有值为Rgb类型,又能让键类型为对象实际存在的键?要求不产生循环引用、无需重复定义颜色名,最终得到代表对象所有键的ColorName类型。

解决方案

可以通过as const断言配合satisfies关键字实现需求,既保留对象键的具体字面量类型,又约束值必须符合Rgb类型,无需重复定义颜色名。

具体实现

type Rgb = `rgb(${number},${number},${number})`;

// 定义颜色对象,用as const推导键的字面量类型,satisfies校验值符合Rgb
const colorNamesToRgb = {
    red: 'rgb(255, 0, 0)',
    green: 'rgb(0, 255, 0)',
    blue: 'rgb(0, 0, 255)',
    yellow: 'rgb(255, 255, 0)',
} as const satisfies Record<string, Rgb>;

// 自动推导对象实际存在的键类型
type ColorName = keyof typeof colorNamesToRgb; // 类型为 "red" | "green" | "blue" | "yellow"

// 函数获得代码补全,仅允许传入合法颜色名
const getRgbByName = (colorName: ColorName) => {
    return colorNamesToRgb[colorName];
};

原理说明

  • as const:强制TypeScript将对象的键和值推导为具体的字面量类型,而非宽泛的string,这样keyof typeof colorNamesToRgb就能得到实际存在的键名联合类型。
  • satisfies:在不改变类型推导结果的前提下,校验对象的每个值是否符合Rgb类型,确保类型安全,避免传入不符合格式的颜色值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:47:15