如何定义NotNominal类型,识别TypeScript非品牌化类型?
如何定义
NotNominal<U>类型过滤品牌化类型 我们先有如下品牌化类型的定义:
declare const nominalSymbol: unique symbol; type Nominal<T extends string, U> = U & { [nominalSymbol]: T };
现在需要实现一个NotNominal<U>类型,满足:
- 当
U不是品牌化类型时,解析结果为U本身 - 当
U是品牌化类型时,解析结果为never
示例期望效果:
type BrandedType = Nominal<'Address', string>; type a = NotNominal<string> // 应解析为 string type b = NotNominal<BrandedType> // 应解析为 never
实现方案
可以通过条件类型结合唯一符号的索引访问来实现,代码如下:
declare const nominalSymbol: unique symbol; type Nominal<T extends string, U> = U & { [nominalSymbol]: T }; type NotNominal<U> = U extends { [nominalSymbol]: unknown } ? never : U; // 验证示例 type BrandedType = Nominal<'Address', string>; type a = NotNominal<string> // 结果:string type b = NotNominal<BrandedType> // 结果:never
逻辑说明
这个实现的核心思路很直接:
- 利用TypeScript的条件类型,检查
U是否能匹配{ [nominalSymbol]: unknown }这个类型约束 - 因为我们定义的品牌化类型是基础类型 + 带有
nominalSymbol属性的对象的交集,所以所有品牌化类型都会满足这个约束 - 若匹配成功(即
U是品牌化类型),返回never;否则返回原类型U
内容的提问来源于stack exchange,提问作者James Paterson
相关产品推荐
相关产品推荐

