比如我的场景是这样的
async function doRequest({ type }) {
}
function wrapper<T>(fn: (arg: T) => Promise<void>): (arg: T) => Promise<void>{
return async function(...args) {
await fn.apply(null, args);
};
}
const myDoRequest = wrapper(doRequest);
这样写,doRequest
的类型( (arg: { type: any; }) => Promise<void>
)符合我的预期。
现在我想扩展一下 wrapper
到支持多个参数,但是下述两种写法都是不行的
async function doRequest({ type, }, { no }) {
}
function wrapper<T>(fn: (...args: T[]) => Promise<void>): (...arg: T[]) => Promise<void>{
return async function(...args) {
await fn.apply(null, args);
};
}
const myDoRequest = wrapper(doRequest);
async function doRequest({ type, }, { no }) {
}
function wrapper<T extends Function>(fn: T): T{
return async function(...args) {
await fn.apply(null, args);
};
}
const myDoRequest = wrapper(doRequest);
这个 wrapper
内部会有一个微妙的报错(虽然不影响返回的类型)
问题 这种高阶函数正确的类型是什么呢?
1
whypool 2019-08-06 11:02:23 +08:00
那有没有低阶,中阶函数?
|
2
otakustay 2019-08-06 11:16:41 +08:00 1
function wrapper<T1>(fn: (arg: T1) => Promise<void>): (arg: T1) => Promise<void>
function wrapper<T1, T2>(fn: (arg1: T1, arg2: T2) => Promise<void>): (arg1: T1, arg2: T2) => Promise<void> function wrapper<T1, T2, T3>(fn: (arg1: T1, arg2: T2, arg3: T3) => Promise<void>): (arg1: T1, arg2: T2, arg3: T3) => Promise<void> 连着这样写 10 个,是 ts 的常用手段 |
3
momocraft 2019-08-06 11:20:24 +08:00 1
首先,目前用 Function#apply 实质是没有类型检查的(不出错只是因为 apply 的参数是 any )
最外层可以这样写 ``` function wrapper<T extends Function>(fn: T): typeof fn { } ``` 里面人工保证吧 |
4
azh7138m OP @otakustay 想到了 HKT 那令人僵硬的写法
@momocraft 如果只要个参数校验其实还是有的,比如这样子 https://www.typescriptlang.org/play/#code/IYZwngdgxgBAZgV2gFwJYHsIwCboEoCmAjggSMgBTJgAOBAXDOQE6oQDmANDBOjPRAQBbAEYFmAShgBvALAAoGEpgKAvgoWIUGLAHdmwGnWYAeACowCAD2QEI2EDABiSKGkwA+CnAiMzEvzlFZWYCZARmLFBIWC03HQoAOmTgZnYQKSDlbJhgXWBUZHgIRMMaABswCkFy8u5U9IkAbgVs1Rb5dXkFKExyGCEwABF8YlJ+gF4YfTLxClxCEjJkZo15QZHF8coARm4diQUgA 里面的函数没泛型的话,一直可以推导正确的类型出来 |
5
terax 2019-08-06 12:00:57 +08:00 via iPhone 1
@momocraft ts3.2 加入了 call apply 的严格类型检查,可以通过 -strictBindCallApply 打开
|
6
zbinlin 2019-08-06 22:26:18 +08:00 2
看下这样行不: //paste.ubuntu.com/p/c23DZyny3W/
|