You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript:推断对象内部泛型对象的类型

嘿,这个问题我之前也碰到过,是TypeScript泛型推断里典型的循环上下文依赖问题,我来给你捋捋原因和解决办法~

首先先把你的代码贴出来方便大家理解:

// 你的类型定义
export type SchemaEntry<A extends object, B> = | Validator<B> | ((obj: A) => Validator<B>);
export type Schema<A extends object> = { [k in keyof A]: SchemaEntry<A, A[k]> };

// 你的函数
function foo<A extends object>(f: Schema<A>): A { return undefined as any; }

// 调用时遇到的问题
const a = foo({ b: new Validator<number>(), c: (o) => new Validator<number>() });
// 参数o的类型无法被正确推断

问题出在哪?

当你调用foo时,TypeScript需要先推断出泛型A的类型,才能知道Schema<A>里那个(o) => Validator<number>函数的参数o应该是什么类型。但尴尬的是,A的类型本身又依赖于这个函数返回的Validator<number>对应的属性类型——等于说“我要先知道A是什么,才能确定o的类型;但我要先确定o的类型,才能知道A是什么”,形成了一个推断循环,TypeScript直接卡壳了。

怎么解决?

给你几个实用的方案,按需选:

1. 最直接:显式指定泛型A

既然TypeScript自己推不出来,那我们直接告诉它A的类型就行,这样o的类型会自动匹配A:

const a = foo<{ b: number; c: number }>({
  b: new Validator<number>(),
  c: (o) => new Validator<number>() // 现在o会被正确推断成{ b: number; c: number }
});

2. 更优雅:用satisfies拆分定义

如果你不想在调用foo时写泛型,可以先单独定义schema,用satisfies关键字约束它的类型,这样TypeScript能提前把o的类型推断出来:

const mySchema = {
  b: new Validator<number>(),
  c: (o: { b: number; c: number }) => new Validator<number>()
} satisfies Schema<{ b: number; c: number }>;

const a = foo(mySchema);

3. 彻底自动:用辅助函数打破推断循环

如果想完全让TypeScript自动推断,不用手动写类型,可以加个辅助函数帮TypeScript分步完成推断:

// 还是用你原来的类型定义
export type SchemaEntry<A extends object, B> = | Validator<B> | ((obj: A) => Validator<B>);
export type Schema<A extends object> = { [k in keyof A]: SchemaEntry<A, A[k]> };

// 加个辅助函数专门用来创建schema
function createSchema<A extends object>(schema: Schema<A>): Schema<A> {
  return schema;
}

// 先创建schema,此时TypeScript会先推断出A的类型,再确定o的类型
const mySchema = createSchema({
  b: new Validator<number>(),
  c: (o) => new Validator<number>() // o现在会被正确推断成{ b: number; c: number }
});

const a = foo(mySchema);

这个方法的核心是通过createSchema把“推断A”和“传入foo”拆成两步,打破了之前的循环,TypeScript就能顺利推导了。

总结

本质上就是TypeScript的泛型推断还没法处理这种“对象类型和内部函数参数类型互相依赖”的循环场景,要么我们手动给它明确类型,要么通过拆分步骤帮它理清推断顺序,问题就解决啦~

内容的提问来源于stack exchange,提问作者Jomik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 02:22:40