![](/img/trans.png)
[英]How to define a generic anonymous function type in TypeScript?
[英]in typescript, how to define a specialized version of a generic function?
如果我有一个通用的 function:
const f1 = <T>(x: T) => console.log(x)
我可以为 f1 定义一个专门的版本:
const f2 = (x: number) => f1(x)
然后 typescript 如果我这样做会抛出一个错误:
f2('6')
但 f2 实际上是另一个调用 f1 的 function。
有没有办法将 f2 定义为 f1 的专用版本? 就像是:
const f2 = f1<number> // this doesn't work
您可以像这样定义泛型类型
type Fn<T = any> = (x: T) => void
const f1: Fn = (x) => console.log(x)
const f2: Fn<number> = f1
f2('6') // Argument of type '"6"' is not assignable to parameter of type 'number'.
这是一个工作游乐场的链接
我将更改您的示例 function 因为类型<T>(x: T)=>void
对泛型类型参数没有任何用处,实际上与(x: unknown)=>void
相同,a具体 function 型。 相反,让我们看一下<T>(x: T)=>T
类型的 function ,它保留输入类型并输出相同类型的值,其中(x: unknown)=>unknown
不够:
const f1 = <T>(x: T) => (console.log(x), x);
// const f1: <T>(x: T) => T
const n: number = 6;
const sixNumber = f1(n); // const sixNumber: number
const s: string = "6";
const sixString = f1(s); // const sixString: string
您要做的是采用通用 function f1
并将其用作(x: number)=>number
类型的具体 function f2
。 这是f1
类型的扩展,因为<T>(x: T)=>T
类型的每个 function 也是(x: number)=>number
类型的 function ,反之亦然。 编译器将此识别为有效的扩展,您可以自己将f2
注释为扩展类型:
const f2: (x: number) => number = f1; // no error
const sixNumberOkay = f2(n); // okay
const sixStringNotOkay = f2(s); // error! string is not number
所以这很好。
--
现在,正如您所指出的,您不能做的是采用f1
的类型和类型number
并自动生成f2
的类型。 类型系统无法让您表示类型参数的替换类型。 f1<number>
和typeof f1<number>
均无效。 TypeScript 对更高种类的类型没有足够的支持来表达这一点,至少不是纯粹在类型级别。
在 TypeScript 3.4 中,TypeScript 引入了对从其他泛型函数推断泛型函数的改进支持。 因此,虽然您不能仅在类型级别上进行您所询问的类型操作,但您可以编写一些函数让编译器无论如何都进行该操作。 例如:
function specify<A extends any[], R>(f: (...a: A) => R) {
return () => f;
}
specify()
function 接受任何 function,即使是通用的,并返回一个新的零参数 function,如果原始的也是通用的。 并且调用时 function 将返回原始 function。 这使您可以这样做:
const f3 = specify(f1)<number>(); // const f3: (x: number) => number
specify(f1)
返回类型为<T>() => (x: T) => T
的 function 。 因此specify(f1)<number>()
产生非通用(x: number)=>number
function。 它也应该在运行时工作:
const sixNumberStillOkay = f3(n); // okay
const sixStringStillNotOkay = f3(s); // error! string is not number
我不确定您是否会经常将通用函数扩展到具体函数,以使specify()
值得; 这取决于你。
好的,希望有帮助; 祝你好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.