TypeScript 初始化指定类型后如何提取变量的字面量类型
解决方案
核心原因
你给变量显式标注: Person类型时,TypeScript 会直接将变量的类型拓宽为Person,彻底丢失实际赋值的字面量信息,as const和显式类型注解同时使用会产生冲突,因此无法直接实现需求。
方案1:使用TS 4.9+ 新增的satisfies操作符(推荐)
satisfies的设计初衷就是解决这类场景:既校验值的结构符合指定类型,又不丢失值本身的原始类型信息,搭配as const即可实现需求:
type Person = { name: string; } // 校验结构符合Person要求,同时保留字面量类型 const john = { name: 'John' } as const satisfies Person; // 此时John的类型为 { readonly name: "John" } type John = typeof john;
如果赋值不符合Person的结构要求,TS会直接抛出类型错误,符合你的约束需求。
方案2:泛型工具函数(兼容TS 4.9以下版本)
如果使用的TS版本较低不支持satisfies,可以通过泛型工具函数实现同等效果:
type Person = { name: string; } // 通用类型约束工具函数 function enforceType<T>() { return <U extends T>(value: U) => value; } const enforcePerson = enforceType<Person>(); const john = enforcePerson({ name: 'John' } as const); // John类型同样为 { readonly name: "John" } type John = typeof john;
该函数只会对入参做类型校验,不符合Person结构就会报错,同时不会修改入参本身的原始类型。
补充说明
如果你不需要字面量带readonly修饰,只需去掉as const即可,两种方案都能正常保留非只读的字面量类型。
内容的提问来源于stack exchange,提问作者Gisheri
相关产品推荐
相关产品推荐

