TypeScript泛型函数回调自动类型推导与强制校验需求
解决TypeScript泛型回调的类型推导与校验问题
问题原因
当前你的库函数funcExample中,TypeScript会同时从values数组和defaultValue回调两个参数推断泛型T。当回调返回对象字面量时,TypeScript会优先把T推断为匿名结构类型(比如{name: string; parent: string}),而非你期望的命名类型Animal;同时因为TypeScript的结构类型兼容规则,回调返回缺少parent这类属性时也不会触发错误。
解决方案
通过NoInfer类型约束回调的返回值,强制泛型T仅从values参数推断,这样既能让myVar自动推导为Animal[],又能让TypeScript严格校验回调返回必须符合T的结构。
修改后的库代码
// 自定义NoInfer类型(TypeScript 4.7+支持,无需外部库) type NoInfer<T> = [T][T extends any ? 0 : never]; type Forced = { name: string; } const funcExample = <T extends Forced>( values: T[], defaultValue: (name: string) => NoInfer<T>, // 用NoInfer约束回调返回类型 ): T[] => { const result = values.map( (value) => { if (value.name === "wrong_condition_that_leads_to_default") { const res = defaultValue(value.name) return res; } const res2 = {...value} return res2; }) return result; }
优化后的用户代码效果
无需手动指定回调返回类型,myVar会自动推导为Animal[]:
type Animal = { name: string, parent: string, } const animals: Animal[] = [ {name: "A", parent: "Y"}, {name: "B", parent: "X"}, {name: "C", parent: "Z"}, ] const myVar = funcExample( animals, (name) => { const t = { name: name, parent: "foo", }; return t; } ) // 自动推导结果:const myVar: Animal[]
强制校验生效
当回调返回缺少parent属性时,TypeScript会直接抛出错误:
const myVar = funcExample( animals, (name) => { const t = { name: name, // 缺少parent属性 }; return t; } ) // 错误提示:类型"{ name: string; }"缺少类型"Animal"中的属性"parent"
原理说明
NoInfer<T>的作用是告诉TypeScript,不要从defaultValue回调这个参数推断泛型T,而是完全依赖values数组的类型来确定T。这样回调的返回值就必须严格匹配T的结构,既解决了类型自动推导的问题,也实现了你需要的强制校验逻辑。
内容的提问来源于stack exchange,提问作者IMCoins
相关产品推荐
相关产品推荐

