TypeScript显式定义类型结构时丢失窄类型,该如何恢复?
问题根源
你自定义的Type类型中,is方法的返回值被硬编码为true | false,当你给boolean字段显式声明as Type<boolean>时,这个签名会直接覆盖isBoolean原有的窄化推导逻辑,导致返回值退化为普通的boolean类型。
解决方案
修改Type类型的is方法签名,将返回值改为基于输入参数类型推导的条件类型,保留窄化能力:
type Type<T extends any> = { name: string; type: T; // 修改is方法返回类型为条件类型,根据输入参数V的类型动态推导返回的布尔字面量 is: <V extends unknown>(v: V) => V extends T ? true : false; typeGuard: (v: unknown) => v is T; }
修改完成后,你原有的其他代码无需调整,调用is方法时的窄化能力就会恢复:
const myType = type(t => t.boolean); // yup3的类型会被正确推导为字面量true const yup3 = myType.is(true); // nope的类型会被正确推导为字面量false const nope = myType.is(123);
该定义具备通用性,后续你扩展string、number等其他类型判断时,只要对应的is方法返回符合V extends 目标类型 ? true : false规则的类型,都可以直接复用这个Type定义。
内容的提问来源于stack exchange,提问作者ken
相关产品推荐
相关产品推荐

