TypeScript 自定义Schema泛型类型报错修复及优化方案问询
问题根因
你代码的核心问题出在类型判断条件T[K] extends {}上:在TypeScript的类型系统中,除了null和undefined之外,所有原始类型(string/number/boolean等)都满足extends {}的判断规则,所以所有属性都会进入递归生成Schema的分支,才会出现你遇到的类型不匹配报错。
基础修复方案
把判断条件替换为extends object即可,object类型在TypeScript中专门指代非原始的引用类型,原始类型不会命中该判断:
type JsType = "boolean" | "string" | "function" | "number" | "symbol" | "undefined" type Schema<T extends object> = { [K in keyof T]: T[K] extends object ? Schema<T[K]> : JsType }
修复后你的cupSchema写法不会再报基础类型错误,所有非对象属性都会被推导为JsType联合类型。
高精度实现方案
如果需要实现严格对应属性类型的字面量校验,只需要新增一个TS类型到JsType字面量的映射规则即可:
// 类型映射:把TS原始类型映射为对应的JsType字面量 type TypeToLiteral<T> = T extends boolean ? "boolean" : T extends string ? "string" : T extends number ? "number" : T extends Function ? "function" : T extends symbol ? "symbol" : T extends undefined ? "undefined" : never type Schema<T extends object> = { [K in keyof T]: // 优先判断函数类型,避免被判定为object进入递归 T[K] extends Function ? TypeToLiteral<T[K]> : T[K] extends object ? Schema<T[K]> : TypeToLiteral<T[K]> }
使用该实现后,Schema<Cup>会被精确推导为:
{ content: { kind: "string", amount: "number" }, isHalfed: "boolean" }
完全符合你要求的高精度校验效果,属性值填写错误时会直接抛出对应类型不匹配的提示。
内容的提问来源于stack exchange,提问作者Alex l.
相关产品推荐
相关产品推荐

