如何让TypeScript函数类型强制要求传入函数接收全部参数?
问题描述
下面这段TypeScript代码能正常编译:
const f1 = (x: string) => { console.log(x) } type F2 = (x: string, y: string) => void; const callF2 = (fn: F2) => { fn("a", "b"); } callF2(f1)
这里callF2要求传入一个带两个参数的函数,但实际却能传入只接受一个参数的f1——这是TypeScript的类型兼容性规则导致的:函数可以忽略多余参数。但我的业务场景里第二个参数是数据库事务,绝对不能允许传入忽略该参数的函数,想让这段代码触发编译错误。
解决方法
有两种实用的方式实现需求:
1. 用泛型严格约束函数参数
通过Parameters工具类型结合泛型,强制传入的函数必须完全匹配F2的参数列表:
const f1 = (x: string) => { console.log(x) } type F2 = (x: string, y: string) => void; // 泛型约束确保函数参数和F2完全一致 const callF2 = <T extends (...args: Parameters<F2>) => void>(fn: T) => { fn("a", "b"); } callF2(f1) // 这里会报错:'(x: string) => void' 无法赋值给 '(x: string, y: string) => void'
这种方式通过泛型的严格校验,让传入的函数必须能接收所有定义的参数,没法跳过第二个参数。
2. 修改函数类型禁止忽略参数
给F2加上...args: never[]剩余参数,这样函数不能忽略任何已定义的参数:
const f1 = (x: string) => { console.log(x) } // 新增never[]剩余参数,强制函数必须处理所有已定义参数 type F2 = (x: string, y: string, ...args: never[]) => void; const callF2 = (fn: F2) => { fn("a", "b"); } callF2(f1) // 触发编译错误:'(x: string) => void' 不符合F2的类型要求
never[]表示函数不能接受额外参数,同时也强制要求必须显式处理所有已声明的参数,自然就没法忽略第二个事务参数了。
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

