【问题标题】:Function input-output template type函数输入输出模板类型
【发布时间】:2019-06-01 02:29:26
【问题描述】:

我见过如下定义的有效模板函数类型:

type func = <I, O>(data: I) => O;

我知道这个模板在某种程度上适用于通用输入和输出类型,但我不知道它是如何实际使用的......

有什么例子吗?我想不出与这样一个模板相匹配的声明。或者它根本就不是模板?我在这里对语法感到困惑。

【问题讨论】:

  • TypeScript(或任何具有类型擦除功能的语言)中并未真正使用“模板”一词。在 C++ 中,它实际上是一个模板,因为编译器会为每次使用它创建真正的代码,而在 Java 或 TypeScript 中,不会在任何地方复制任何内容。
  • @jcalz 不确定这对我们有什么帮助。
  • 这只是一个术语注释。我现在正在写答案。

标签: typescript


【解决方案1】:

我不确定您在哪里看到使用该类型,但它是一个 具体 类型,代表 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

如果您所做的只是在声明函数时插入IO 的具体值,那么这样做没有多大意义。但是,您可能希望使用像 Func&lt;I, O&gt; 这样的泛型类型是有原因的,最明显的是在高阶类型的数据类型中。

例如,如果你想创建一个高阶函数 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&lt;I, O&gt; 的内容并像 Funky 一样记住它。或者也许某人实际上使用了这样的Funky 类型,出于某些只有他们知道的邪恶目的(除非您查看它在做什么或将其链接到您的问题中) )。

无论如何,希望对您有所帮助。祝你好运!

Link to code

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    相关资源
    最近更新 更多