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
相关产品推荐
相关产品推荐

