支付 API tradePay 失败回调是否包含参数,TypeScript 如何定义?
明确结论
tradePay 的 fail 回调在运行时可以接收失败结果对象。文档示例中的回调参数就是实际调用方式。如果 mini-types 将其声明为 fail?: () => void,通常是因为类型声明不完整、版本较旧,或遗漏了回调参数,并不表示运行时不会传参。
失败对象的字段应以当前平台文档和真机返回结果为准。常见字段可能有 error、errorMessage,但客户端版本、支付渠道和失败场景不同,返回结构也可能不同。未经确认的字段不要全部声明为必填。
推荐写法
可以在业务代码中定义一个本地类型,将不稳定的字段设为可选:
interface TradePayFailResult {
error?: number | string;
errorMessage?: string;
[key: string]: unknown;
}
type TradePayFailCallback = (result: TradePayFailResult) => void;
调用时:
my.tradePay({
tradeNO: 'your_trade_no',
success(result) {
console.log('支付成功:', result);
},
fail: ((result: TradePayFailResult) => {
console.error('支付失败:', result);
console.error('错误码:', result.error);
console.error('错误信息:', result.errorMessage);
}) as unknown as () => void,
});
这里的类型转换只是为了兼容 mini-types 中错误或不完整的 () => void 声明,不会影响运行时行为。
更稳妥的封装方式
如果不想在每次调用时都写类型转换,可以增加一层封装:
interface TradePayFailResult {
error?: number | string;
errorMessage?: string;
[key: string]: unknown;
}
interface TradePayOptions {
tradeNO: string;
success?: (result: unknown) => void;
fail?: (result: TradePayFailResult) => void;
complete?: (result: unknown) => void;
}
function tradePay(options: TradePayOptions): void {
my.tradePay(options as unknown as Parameters<typeof my.tradePay>[0]);
}
业务代码:
tradePay({
tradeNO: 'your_trade_no',
success(result) {
console.log('支付成功:', result);
},
fail(result) {
console.error(result.error, result.errorMessage);
},
});
这样可以把类型兼容逻辑集中在一处。以后官方类型修正后,只需修改封装层。
为什么不能直接写带参数的回调
假设 mini-types 当前的声明是:
fail?: () => void;
开启严格类型检查后,下面的代码可能报错:
my.tradePay({
tradeNO: 'your_trade_no',
fail(result: TradePayFailResult) {
console.error(result);
},
});
类型定义表明调用方可以不传参数,而你的函数要求必须接收一个参数,因此 TypeScript 会认为两者不完全兼容。这个报错只能说明声明文件与代码存在冲突,不能证明运行时没有回调参数。
也可以修正声明文件
如果已经确认项目使用的 mini-types 版本和接口名称,也可以通过声明合并修正类型:
interface TradePayFailResult {
error?: number | string;
errorMessage?: string;
[key: string]: unknown;
}
再根据 mini-types 实际暴露的模块、命名空间和参数接口进行扩展,将 fail 改为:
fail?: (result: TradePayFailResult) => void;
声明合并代码必须与当前安装包中的真实模块名和接口名一致,不能靠猜测。如果原接口已经将 fail 声明为 () => void,TypeScript 的属性声明合并可能不允许用不同类型重新声明。遇到这种情况,本地封装通常更省事。
注意事项
- 优先升级到与当前开发工具和运行环境匹配的最新版
mini-types,确认类型差异是否已经修复。 - 不要根据某一次失败结果,就把所有观察到的字段都声明为必填。
error的实际类型可能受 SDK 版本影响。如果当前官方文档无法确认,使用number | string比限定为单一类型更稳妥。fail表示接口调用或支付流程失败。支付业务的最终状态仍需通过服务端查询或异步通知确认,不能只依赖客户端回调。as unknown as () => void只用于绕过已知的类型声明缺陷,不适合作为常规类型设计。项目中的相关调用较多时,建议统一封装。
备注:内容仅供参考。