如何让TypeScript函数根据传入的注册对象自动推断回调参数类型
TypeScript:让回调参数自动推断为当前对象类型
我需要实现一个call函数,用来注册包含回调的对象并存储,但编译器始终无法自动识别回调的唯一参数就是该对象本身。下面是我试过的两种写法,都存在类型推断问题:
尝试V1
type CallbackData<T> = { callback: (data: T) => void } function call<T>(data: T & CallbackData<T>) { data.callback(data); } call({ test: '', // 错误:ts(2345) callback: data => { } // 这里的data应该自动推断为当前对象的类型 })
尝试V2
type CallbackData<T> = { callback: (data: T) => void } function call<T extends CallbackData<T>>(data: T) { data.callback(data); } call({ test: '', callback: data => { } // 错误:ts(2322) // 这里的data应该自动推断为当前对象的类型 });
正确解决方案
问题出在泛型推断的顺序上,我们需要让TypeScript先确定对象的完整类型,再关联回调的参数类型。最直接的写法是把约束直接定义在泛型上:
function call<T extends { callback: (self: T) => void }>(data: T) { data.callback(data); } // 现在可以正常使用,data参数自动推断为当前对象类型 call({ test: '示例文本', callback: data => { console.log(data.test); // 类型正确,无报错 } });
如果需要复用回调类型,可以单独定义:
type SelfCallback<T> = { callback: (self: T) => void }; function call<T extends SelfCallback<T>>(data: T) { data.callback(data); } call({ id: 123, callback: data => { console.log(data.id); // 类型推断正常 } });
这种写法让TypeScript先推断出整个对象的类型T,然后强制回调的参数类型等于T,完美解决了之前的推断错误问题。
内容的提问来源于stack exchange,提问作者Dutch
相关产品推荐
相关产品推荐

