Typescript 泛型函数类型字面量

Typescript Generic Function Type Literals

这是有效的,没问题:

type fun = (uid: string) => string 

const abc: fun = value => value

const efg = (callback:fun, value:string) =>callback(value)

console.log(efg(abc, "123"))

但是如果我们使用泛型,它会报错:

type fun = (uid: string) => string 

const abc: fun = value => value

const efg = <T>(callback:T, value:string) =>callback(value)

console.log(efg(abc, "123"))

错误:

This expression is not callable. Type 'unknown' has no call signatures.(2349)

TypeScript Playground demo

我读过 https://www.typescriptlang.org/docs/handbook/generics.html 但它没有提到通用函数类型文字。

我需要将不同的函数作为参数传递,这就是我需要这个的原因。

是否有任何工作 around/hack 或者实际上有正确的方法来做到这一点?

以下基于 rxjs's UnaryFunction 的内容可能适合您。

TypeScript Playground demo:

interface Callable<T> {
    (source: T): T;
}

interface CallableInvoker<T> {
    // If the return type also needs to be T, replace any with T
    (callback: Callable<T>, value: T): any
}


function doubleNumber(value: number): number {
    return value * 2;
}

function doubleString(value: string): string {
    return value + value;
}

const efg: Callable<number> = doubleNumber; // Valid
const efg2: Callable<number> = doubleString; // Invalid, doubleString  must match the generic type

const efg3: CallableInvoker<number> = (doubleNumber, value) => doubleNumber(5);

问题是T类型没有限制,所以可以是任何类型,你可以传numberstring等,很明显你不能调用number 就像它会起作用一样。

您在代码中对待 T 的方式与使用 string 参数的方式相同,因此需要给出此类约束。考虑:

const efg = <T extends (a: string) => any>(callback: T, value: string) => callback(value)

以上 T 被限制(通过 extend 关键字)作为一个接受 string 并且可以 return 任何东西的函数。这意味着 string->number, string-> boolean, string->object 等所有功能都可以。

我们可以走得更远并对其进行更多约束(如果需要)并说我们的功能只有 string->string,而正是这样的接口由 fun 类型给出。所以让我们扩展 fun:

const efg = <T extends fun>(callback: T, value: string) => callback(value)

Playground