我不确定您在哪里看到使用该类型,但它是一个 具体 类型,代表 generic function:
type Funky = <I, O>(data: I) => O;
如果你有一个Funky 类型的函数,你可以在任何你想要的任何类型的单个参数上调用它(因为I 不是constrained),它可以产生任何类型的输出想要(O 也不受限制)。
正如您所注意到的,很难想象这样的功能。在像 Haskell 这样的更健全的类型语言中,它会是 impossible to implement that 而没有一些 evil magic。 TypeScript 可以让你 assert 几乎任何东西,所以你可以编写一个没有编译器警告的实现,但它仍然是一个非常不安全的函数:
const unsafeCoerce: Funky = (x: any) => x; // any is an escape-hatch from the type system
这里,unsafeCoerce 只是返回其输入,这意味着它应该允许调用者将其输入强制转换为您想要的任何类型,即使那是谎言:
const threeAsString: string = unsafeCoerce(3); // DANGER ?
// const unsafeCoerce: <number, string>(data: number) => string
threeAsString.charAt(0); // no error at compile time, TypeError at runtime ?
所以我也没有看到该功能有多大用处。
具有非常不同含义的相似类型是:
type Func<I, O> = (data: I) => O;
这是一个通用类型,代表一个具体函数(或者,一个具体函数族)。你不能拥有Func 类型的函数,因为它没有指定它的泛型参数:
const nope: Func = (x: any) => x; // error!
// ~~~~ <-- Generic type 'Func' requires 2 type argument(s).
相反,您需要指定参数,它变成了从某种特定输入类型到某种特定输出类型的函数,这更容易获得:
const stringLength: Func<string, number> = x => x.length; // okay
如果您所做的只是在声明函数时插入I 和O 的具体值,那么这样做没有多大意义。但是,您可能希望使用像 Func<I, O> 这样的泛型类型是有原因的,最明显的是在高阶类型的数据类型中。
例如,如果你想创建一个高阶函数 apply(f, x),它接受一个函数 f 和一个参数 x 并返回 f(x),你会发现自己想要使用像 Func 这样的类型:
function apply<I, O>(f: Func<I, O>, x: I): O {
return f(x); // okay
}
const out = apply((x: number) => x.toLocaleString(), 123); // string
可能您看到类似 Func<I, O> 的内容并像 Funky 一样记住它。或者也许某人实际上使用了这样的Funky 类型,出于某些只有他们知道的邪恶目的(除非您查看它在做什么或将其链接到您的问题中) )。
无论如何,希望对您有所帮助。祝你好运!
Link to code