我看到了如下定义的有效模板函数类型:
type func = <I, O>(data: I) => O;
我知道此模板在某种程度上适用于通用输入和输出类型,但是我无法弄清楚它如何实际使用...
有什么例子吗?我无法提出与此类模板匹配的声明。还是根本不是模板?我对语法感到困惑。
答案 0 :(得分:1)
我不确定您在哪里看到了该类型,但是它是表示<{3}}的具体类型:
type Funky = <I, O>(data: I) => O;
如果您具有类型Funky
的函数,则可以在任何所需类型的绝对单个参数上调用它(因为I
不是generic function),并且可能产生您想要的任何类型的输出(O
也不受约束)。
您已经注意到,很难想象这样的功能。在类似Haskell的更合理类型的语言中,它将是constrained而没有一些impossible to implement that。 TypeScript使您可以evil magic进行几乎所有操作,因此您可以编写没有编译器警告的实现,但这仍然是一个非常不安全的功能:
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;
这是泛型类型,表示 concrete 函数(或一系列具体函数)。您无法使用类型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
类型,出于某种邪恶的目的,只有他们知道(除非您查看它在做什么或将其链接到其中)您的问题)。
无论如何,希望能有所帮助。祝你好运!