如何创建类型,仅允许传入常量对象属性而非字符串值?
实现仅允许传入常量对象属性值的类型
要实现你需要的效果,核心是利用TypeScript的**品牌类型(Branded Type)**区分普通字符串和常量对象的属性值,结合as const断言让TypeScript严格推断字面量类型。具体步骤如下:
1. 定义品牌类型
通过添加一个仅存在于类型层面的“品牌”标识,让普通字符串无法匹配目标类型:
type BrandedConstant<T extends string> = T & { __brand: 'MyConstant' };
2. 包装常量值
编写工具函数将常量值转换为品牌类型(运行时无额外开销,仅做类型标记):
const wrapConstant = <T extends string>(value: T): BrandedConstant<T> => { return value as BrandedConstant<T>; };
3. 定义带类型标记的常量对象
用as const断言确保TypeScript推断出具体的字面量类型,而非宽泛的string:
const MY_CONSTANTS = { A: wrapConstant('a'), B: wrapConstant('b'), C: wrapConstant('c') } as const;
4. 生成目标类型
从常量对象中提取所有属性的类型:
type MyConstant = typeof MY_CONSTANTS[keyof typeof MY_CONSTANTS];
5. 定义目标函数
将参数类型设为MyConstant:
function doSomething(value: MyConstant) { // 业务逻辑 }
验证效果
doSomething(MY_CONSTANTS.A); // ✅ 正常通过类型检查 doSomething('a'); // ❌ 类型报错:普通字符串无法赋值给品牌类型 doSomething('d'); // ❌ 类型报错:不在常量范围内
原理说明
as const让TypeScript将常量值推断为具体的字面量类型(如'a'而非string);- 品牌类型通过额外的
__brand属性(仅存在于类型系统),让TypeScript区分普通字符串和我们标记的常量值,实现你需要的限制效果。
内容的提问来源于stack exchange,提问作者Ivan Banha
相关产品推荐
相关产品推荐

