如何用TypeScript根据函数返回类型推断参数类型?
实现符合要求的MyFunc类型
要实现你需要的类型约束,我们可以通过泛型约束+严格类型交叉的方式完成,既让参数类型从返回类型自动推断,又严格限制返回值不能有多余属性。
类型定义
type MyFunc<R extends { foo: unknown }> = (param: R['foo']) => R & Record<Exclude<keyof R, 'foo'>, never>;
用法示例
正确场景
// 声明返回类型为{ foo: boolean },param自动推断为boolean类型 const myBoolFunc: MyFunc<{ foo: boolean }> = (param) => { return { foo: param }; // 完全符合要求,无报错 }; // 同理,返回类型指定为{ foo: string },param自动是string类型 const myStringFunc: MyFunc<{ foo: string }> = (param) => { return { foo: `Hello ${param}` }; };
错误场景(自动校验)
- 返回多余属性:
const invalidFunc1: MyFunc<{ foo: number }> = (param) => { return { foo: param, bar: "多余属性" }; // ❌ 报错:bar属性类型不符合never约束 };
- 参数与返回值类型不匹配:
const invalidFunc2: MyFunc<{ foo: string }> = (param) => { return { foo: 123 }; // ❌ 报错:返回值foo的number类型与指定的string不匹配 };
原理说明
- 泛型参数
R被约束为必须包含foo属性,通过R['foo']直接将参数param的类型与返回值中foo的类型绑定,实现参数类型的自动推断; R & Record<Exclude<keyof R, 'foo'>, never>这个交叉类型的作用是严格限制返回值只能有foo属性:如果R中存在除foo外的其他属性,Exclude<keyof R, 'foo'>会提取这些属性名,Record将这些属性的类型设为never,此时返回值中出现这些属性就会触发类型错误,因为never类型无法被任何值赋值。
内容的提问来源于stack exchange,提问作者johann1301s
相关产品推荐
相关产品推荐

