如何基于第一个传入对象的具体类型推断函数第二个参数类型
解决TypeScript函数参数匹配实际对象结构的问题
核心问题分析
你定义的exampleObject被显式标注为Example接口类型,TypeScript会自动将其类型拓宽为接口的宽泛类型,丢失了实际值的具体结构信息。要让函数第二个参数严格匹配第一个参数的实际结构,而非接口类型,需要分两步处理:
步骤1:让变量保留实际字面量类型(同时满足接口约束)
如果要保留变量实际值的具体类型,同时确保它符合Example接口,推荐使用TypeScript 4.9+新增的satisfies关键字:
interface Example { item1?: { item1?: string, item2?: string, }, item2?: { item1?: string, item2?: string, } } // 用satisfies约束对象符合Example接口,同时保留字面量类型 const exampleObject = { item1: { item1: 'test' } } satisfies Example;
若你的TypeScript版本低于4.9,可通过as const结合类型断言实现相同效果:
const exampleObject = { item1: { item1: 'test' } } as const as Example;
步骤2:定义匹配类型的函数
直接将函数的第二个参数类型设置为与第一个参数相同的泛型T,TypeScript会自动推断第一个参数的实际字面量类型,并强制第二个参数完全匹配:
function exampleFunction<T>(a: T, b: T) { // 函数逻辑实现 }
验证效果
此时调用函数时,不符合实际结构的参数会被TypeScript报错:
// ✅ 合法:与第一个参数的实际结构完全一致 exampleFunction(exampleObject, { item1: { item1: 'test' } }); // ❌ 不合法:item1多了item2属性,与实际结构不匹配 exampleFunction(exampleObject, { item1: { item1: 'test', item2: 'test' } }); // ❌ 不合法:新增了item2属性,与实际结构不匹配 exampleFunction(exampleObject, { item2: {} });
补充说明
如果必须保留exampleObject的Example类型标注(即const exampleObject: Example = ...),TypeScript会丢失实际值的具体结构信息,此时无法实现严格匹配实际结构的需求——因为类型系统只能识别到它符合Example接口,而非具体的字面量结构。这种情况下只能修改变量定义来保留字面量类型。
内容的提问来源于stack exchange,提问作者Mateusz
相关产品推荐
相关产品推荐

