如何定义仅接受单个对象参数的TypeScript函数类型?
如何定义仅接受单个对象类型参数的TypeScript函数类型?
要实现仅允许单个对象类型参数的函数赋值给目标类型,核心难点在于函数参数的逆变特性:宽泛参数类型的函数(如(arg: object) => any)无法接受更具体参数类型的函数(如(arg: {str: string}) => {}),因为后者只能处理特定结构的对象,不满足前者“能处理任意对象”的要求。
以下是可行的实现方案:
方案一:泛型辅助函数+条件类型约束
这是最安全且符合需求的方式,通过条件类型检查函数参数是否为对象类型,辅助函数负责约束赋值过程:
// 定义类型工具:判断函数的唯一参数是否为对象类型 type ObjectParamFunction<F> = F extends (arg: infer U) => any ? U extends object ? F : never : never; // 辅助函数,用于约束赋值操作 const assignObjectParamFun = <F>(fn: ObjectParamFunction<F>): F => fn; // 使用示例 let fun = assignObjectParamFun((arg: object) => {}); // ✅ 合法 fun = assignObjectParamFun((arg: {}) => {}); // ✅ 合法 fun = assignObjectParamFun((arg: {str: string}) => {}); // ✅ 合法 fun = assignObjectParamFun((arg: {obj: {}, num: number}) => {}); // ✅ 合法 fun = assignObjectParamFun((arg: number) => {}); // ❌ 错误:非对象参数的函数无法通过约束
方案二:直接定义泛型类型(需类型断言)
如果不想使用辅助函数,可直接定义泛型类型,但赋值时需要手动添加类型断言(安全性略低):
type RestrictToObjectParam = <U extends object>(arg: U) => any; let fun: RestrictToObjectParam; fun = ((arg: object) => {}) as RestrictToObjectParam; // ✅ 合法 fun = ((arg: {}) => {}) as RestrictToObjectParam; // ✅ 合法 fun = ((arg: {str: string}) => {}) as RestrictToObjectParam; // ✅ 合法 fun = ((arg: {obj: {}, num: number}) => {}) as RestrictToObjectParam; // ✅ 合法 fun = ((arg: number) => {}) as RestrictToObjectParam; // ❌ 错误:类型转换不兼容
为什么之前的尝试无效?
(arg: object) => any:受逆变特性限制,仅接受能处理任意对象的函数,具体结构的对象参数函数无法赋值。<T extends object>(arg: T) => any:TypeScript会将泛型T推断为最宽泛的object类型,本质等价于(arg: object) => any,同样无法兼容具体对象参数的函数。T extends object ? (arg: T) => void : never:条件类型最终会被解析为(arg: object) => void,依然受逆变特性约束,无法满足需求。
内容的提问来源于stack exchange,提问作者D. Johnson
相关产品推荐
相关产品推荐

