如何让TypeScript函数自动推断传入类实例的泛型类型?
泛型函数requireParams的类型自动推断实现方案
需求背景
需要构建泛型函数requireParams,用于确保类初始化时特定属性已被设置(动态数据场景下无法通过必填参数直接约束),希望函数能自动从传入的类实例参数推断泛型类型,无需手动指定。
当前实现代码
export const requireParams = (cls: AnyClass, requiredParams: string[]) => { if (!requiredParams) { return; } const missingParams = requiredParams.filter( (param) => cls?.[param] === undefined || cls?.[param] === null || cls?.[param] === NaN ); if (missingParams.length) { throw new Error(`Missing required params: ${missingParams.join(", ")}`); } };
使用示例
class Foo { constructor(public readonly food: string) { requireParams(this, ['food']); } }
尝试过的无效类型定义
type AnyClass<T> = T extends new (...args: any[]) => infer R ? R : never;
该定义试图从构造函数推断实例类型,但因函数实际接收的是类实例而非构造函数,导致泛型参数T始终返回never。
解决方案
核心问题是之前的类型推断方向错误:函数接收的是类实例而非构造函数,因此需要基于实例类型做泛型约束,而非构造函数。修改后的实现如下:
export const requireParams = <T extends object>(obj: T, requiredParams: Array<keyof T>) => { if (!requiredParams.length) { return; } const missingParams = requiredParams.filter( (param) => obj[param] === undefined || obj[param] === null || Number.isNaN(obj[param]) ); if (missingParams.length) { throw new Error(`Missing required params: ${missingParams.join(", ")}`); } };
关键优化点
- 泛型约束自动推断:
<T extends object>会自动从传入的obj(即类实例this)推断出具体的实例类型,无需手动指定 - 参数类型校验:
Array<keyof T>限制必填参数必须是实例T的属性键,避免传入不存在的属性名,同时提供类型提示 - 修正NaN判断:原代码中
cls?.[param] === NaN永远为false(NaN不等于任何值),替换为Number.isNaN()实现正确判断
优化后使用效果
class Foo { constructor(public readonly food: string) { requireParams(this, ['food']); // 类型匹配,无报错 // requireParams(this, ['nonExistent']); // TS直接报错:属性"nonExistent"不存在于类型"Foo" } }
内容的提问来源于stack exchange,提问作者brandonscript
相关产品推荐
相关产品推荐

