TypeScript泛型约束继承时styleVariants多余属性无TS报错问题
问题原因
TS 的默认类型兼容规则为结构赋值,只要传入对象包含目标类型的所有必填属性,即使存在多余属性也会被判定为兼容。你定义的 AllowedStyles 所有属性都是可选的,所以即使传入拼写错误的属性(比如 colr),TS 也不会判定为违反类型约束,因此不会抛出报错。
解决方案
新增 Exact 工具类型强制禁止多余属性,再递归校验 styleVariants 最内层的结构,同时保留泛型的精确类型推断能力,修改后的完整类型定义如下:
// 原有基础类型定义 type AllowedStyles = { color?: 'red'; backgroundColor?: 'red'; }; type StyleVariantsStructure = { [k: string]: { [k: string]: AllowedStyles; }; }; // 新增:Exact 工具类型,禁止对象出现 Shape 之外的多余属性 type Exact<Shape, T> = T extends Shape ? T & { [K in Exclude<keyof T, keyof Shape>]: never } : never // 新增:递归校验 styleVariants 每一层的最内层结构 type ValidateStyleVariants<T> = { [K in keyof T]: { [V in keyof T[K]]: Exact<AllowedStyles, T[K][V]> } } // 修改后的函数定义 function myStyles<T extends StyleVariantsStructure>(params: { baseStyles: Exact<AllowedStyles, typeof params.baseStyles>; styleVariants: T & ValidateStyleVariants<T>; }): T { return params.styleVariants; }
效果验证
修改后如果在 styleVariants 最内层写入拼写错误的属性(比如 colr),TS 会直接抛出类型错误,同时函数返回值依然会保留你传入的 styleVariants 的精确类型,两个需求都可以满足。
内容的提问来源于stack exchange,提问作者Will Despard
相关产品推荐
相关产品推荐

