TypeScript类型推断问题:传入类schema返回unknown而非预期类类型
问题原因
你的泛型约束写法导致TypeScript无法正确推导T的类型。当传入MyClass(类构造函数)时,Schema extends (new () => T)这个约束是让Schema适配T,但TypeScript的类型推导逻辑是正向的——它更擅长从输入类型推导泛型参数,而非从约束反向推导T。此时T没有明确的输入来源,TypeScript只能将其推断为unknown,最终返回类型也就变成了unknown | null。
修复方案
可以通过两种方式调整类型定义,让TypeScript正确推导返回类型:
方案1:用InstanceType直接提取类实例类型
去掉冗余的泛型参数T,直接通过InstanceType工具类型从构造函数中提取实例类型,无需手动推导:
type DefaultEntity = { id: string; createdBy: string; [fieldName: string]: unknown; }; abstract find<Schema extends string | new () => unknown>( schema: Schema, id: string, ): Promise<(Schema extends string ? DefaultEntity : InstanceType<Schema>) | null>;
当传入类构造函数时,InstanceType<Schema>会自动提取它的实例类型,比如传入MyClass,返回类型会被推断为Promise<MyClass | null>;传入字符串时,返回Promise<DefaultEntity | null>,完全符合预期。
方案2:调整泛型参数的依赖关系
如果想保留T作为泛型参数,可以把T设为核心参数,让schema的类型约束依赖T:
type DefaultEntity = { id: string; createdBy: string; [fieldName: string]: unknown; }; abstract find<T = DefaultEntity>( schema: T extends DefaultEntity ? string : (new () => T), id: string, ): Promise<T | null>;
这里通过条件类型让schema在T为DefaultEntity时接受字符串,否则接受对应类的构造函数。传入MyClass时,T会被直接推导为MyClass的实例类型,返回类型为Promise<MyClass | null>;传入字符串时,T默认是DefaultEntity,返回类型也符合预期。
内容的提问来源于stack exchange,提问作者Ruudy
相关产品推荐
相关产品推荐

