您可以在 this playground 中看到演示.
我制作了一个简单的泛型类型,它可以表示一个变量或一个返回变量的函数。但是,不幸的是,它不适用于典型的 typeof arg === 'function'
查看。它产生以下错误:This expression is not callable.
Not all constituents of type '(() => T) | (T & Function)' are callable.
Type 'T & Function' has no call signatures.
有没有办法让它在不使用类型保护功能的情况下工作?
type Initializer<T> = T | (() => T)
function correct(arg: Initializer<string>) {
return typeof arg === 'function' ? arg() : arg
}
function wrong<T>(arg: Initializer<T>) {
return typeof arg === 'function' ? arg() : arg // error here
}
const isFunction = (arg: any): arg is Function => typeof arg === 'function'
function correct_2<T>(arg: Initializer<T>) {
return isFunction(arg) ? arg() : arg
}
最佳答案
你可以写:
type Initializer<T> = T extends any ? (T | (() => T)) : never
function correct<T>(arg: Initializer<T>): T {
return typeof arg === 'function' ? arg() : arg // works
// arg is Initializer<T> & Function in the true branch
}
const r1 = correct(2) // const r1: 2
const r2 = correct(() => 2) // const r2: number
在原始版本中,
arg
已解析为 (() => T) | (T & Function)
在真正的分支中。 TS 显然无法识别这种联合函数类型,即两个成分都是可调用的。至少在以上版本中,编译器很清楚您可以调用 arg
功能检查后。可能也值得 create a github issue对于 TypeScript 存储库中的这种情况 - 在我看来
T & Function
应该代表某种(宽)类型的功能。
关于 typescript 类型 T 或函数 () => T 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60898079/