TypeScript开启strict模式下util.promisify报参数不匹配错误求助
你遇到的这个问题,本质上是util.promisify的TypeScript类型定义与firebird-node库的attach函数签名不兼容导致的,严格来说不算util.promisify的“已知Bug”,更偏向于类型系统对非标准回调函数的适配问题。
为什么会出现这个错误?
TypeScript的util.promisify类型定义默认是为标准Node.js回调风格函数设计的——也就是函数的最后一个参数是(err: Error | null, result: T) => void这样的回调,并且原函数的参数数量会被严格推导。
如果firebird-node的attach函数类型签名不符合这个预期(比如参数列表里有额外的可选参数、回调的位置/结构和标准定义有差异),在strict: true模式下,TypeScript会严格检查promisify后函数的参数个数,就会抛出你看到的Expected 2 arguments, but got 1错误。
举个例子,如果attach的类型定义被写成了类似:
function attach(params: ConnectionParams, optionalArg?: any, callback: (err: Error | null, db: Database) => void): void;
那么util.promisify会错误地推断出promisify后的函数需要2个参数(params和optionalArg),但实际调用时你只传了connectionParams,类型检查自然会报错。
你的手动Promise方案为什么可行?
手动封装Promise相当于绕开了util.promisify的类型推导,直接明确了函数的输入输出类型,完全贴合attach的实际调用逻辑,所以不会触发类型错误,这也是这种场景下最稳妥的解决方案之一:
const attachAsync = (params: ConnectionParams) => new Promise<Database>((resolve, reject) => { fb.attach(params, (err, db) => { err ? reject(err) : resolve(db); }); });
其他可选的解决方式
类型断言绕过检查:如果你不想手动封装,可以用类型断言强制指定promisify后函数的类型:
import util from 'util'; import fb from 'firebird-node'; const attachAsync = util.promisify(fb.attach) as (params: ConnectionParams) => Promise<Database>;这种方式能快速解决类型错误,但缺点是如果后续
attach的签名变化,类型断言可能会隐藏潜在问题。检查库的类型定义更新:可以去firebird-node的仓库看看是否有相关的Issue,或者提交一个Issue给作者,建议修正
attach函数的类型签名,使其符合标准Node.js回调风格,这样util.promisify就能自动正确推导类型了。
内容的提问来源于stack exchange,提问作者kattunga

