TypeScript如何在不影响类型本身的前提下存储可提取的类型元数据
TypeScript 类型元数据存储方案
结论
可以实现,通过变种的类型Brand技巧即可做到元数据可提取、同时完全不影响原类型的实际取值,无需额外调用过滤工具类型。
实现代码
// 元数据标记类型:和never交叉,联合到其他类型时会自动消去不影响取值 type Metadata<MetaType> = { __hidden_meta_field?: MetaType } & never // 元数据提取工具类型 type ExtractMetadata<T> = T extends { __hidden_meta_field?: infer R } ? R : never
使用示例
// 给number类型附加string类型的元数据 type TestType = number | Metadata<string> // 验证原类型功能不受影响 const num1: TestType = 100 // 正常赋值 const num2: TestType = "text" // 类型报错,符合number的取值约束 const pureNum: number = num1 // 可直接赋值给原生number类型,无兼容问题 // 验证元数据可正常提取 type MetaResult = ExtractMetadata<TestType> // 提取结果为 string,符合预期
实现原理
Metadata<MetaType>本质是和never交叉的类型,而never属于所有类型的子类型,和任意类型做联合运算时会被自动消去,T | never恒等于T,因此完全不会改变原类型的取值范围。- TypeScript 的条件类型推断逻辑不会忽略
__hidden_meta_field这个标记结构,因此可以通过infer关键字正常提取出存储的元数据类型。
内容的提问来源于stack exchange,提问作者Maciej Kravchyk
相关产品推荐
相关产品推荐

