有两种函数类型,一种返回string
,另一种返回Promise<string>
。现在,我想要一个包装它们的函数,但是在调用fn
type FuncTypes = (...args: any[]) => string | Promise<string>
function callFunc(fn: FuncTypes, ...args: any[]) {
// distinguish fn returns string or Promise<string>
// if fn returns string
return new Promise<string>(r => r(fn.call(this, ...args)))
// if fn returns a Promise
return fn.call(this, ...args)
}
另一种情况是过载:
type FuncA = (...args: any[]) => string
type FuncB = (...args: any[]) => Promise<string>
function callFunc(fn: FuncA, ...args: any[]): Promise<string>
function callFunc(fn: FuncB, ...args: any[]): Promise<string>
function callFunc(fn: any, ...args: any[]): Promise<string> {
// if fn is instanceof FuncA
// do sth.
// else if fn is instanceof FuncB
// do sth
}
尽管我们可以简单地使用const returned = fn(..args); typeof returned === 'string'
来检查返回的类型,但这不是一般的解决方案。如果函数类型为() => AnInterface|AnotherInterface
,则很难使用typeof
或instanceof
来检查返回类型。
有什么通用的方法可以区分它们吗?还是应该为每种类型编写两个函数?
答案 0 :(得分:1)
有两种函数类型,一种返回字符串,另一种返回Promise。现在,我想要一个包装它们的函数,但是在调用fn时我必须区分每个包裹
在这种特定情况下, jsonobjects = $.grep(jsonobjects, function( value ) {
return value.id !== id;
});
可能就是这样:
callFunc
如果function callFunc(fn: FuncTypes, ...args: any[]) {
return <Promise<string>>Promise.resolve(fn.call(this, ...args));
}
返回承诺,则fn
的承诺将被Promise.resolve
返回的承诺所替代;否则,您将获得一个已解决的承诺,将返回值fn
作为其解决值。
有什么通用的方法可以区分它们吗?
不是在运行时,除非您以某种方式(稍后再进行注释)对其进行注释。 TypeScript的类型信息仅在编译时。
还是我应该为每种类型编写两个函数?
那可能是最好的。
您可以对函数进行注释,例如,通过在函数上放置一个属性来指示其返回类型:
fn
到那时,您正在复制类型信息(一次用于TypeScript,再次一次用于您自己的代码)。
因此,编写两个函数的解决方案可能是最好的。