【问题标题】:Language Agnostic - Allowable types in function and constructor parameters语言不可知论 - 函数和构造函数参数中允许的类型
【发布时间】:2020-03-13 17:32:54
【问题描述】:

大多数(如果不是所有)静态类型语言都允许您为函数或构造函数参数指定单一类型;例如

function foo(x: string) { ... }

foo("hello")  // works
foo(123)      // error

TypeScript 是 JavaScript 的静态类型超集,但由于 JavaScript 是动态类型语言,TypeScript 允许您更灵活一点;例如,您可以指定多个 allowable 类型。

function foo(x: string | number) { ... }

foo("hello")  // works
foo(123)      // works
foo(true)     // error

此外,在 TypeScript 中,这允许您将泛型类型参数仅限制为特定类型;例如:

class Foo<T extends number | string> {
    constructor(x: T) { ... }
}

new Foo("hello")  // works
new Foo(123)      // works
new Foo(true)     // fails

问题

我喜欢 TypeScript 将泛型类型参数仅限制为特定类型的能力,但我也希望能够在其他语言中做到这一点,即 C# 和 Kotlin,但据我所知,没有等效的构造在这些语言中支持这样的约束。用其他语言如何实现这一点?

注意:我很乐意接受任何语言的答案,而不仅仅是列出的那些。这更多的是关于更高层次的思考和探索可以跨语言应用的其他途径。

【问题讨论】:

  • 对于C#,第一种情况可以使用方法重载

标签: javascript c# typescript kotlin language-agnostic


【解决方案1】:

F# 中有 Sum / Union 类型。看起来很像 TypeScript 中的内容,但在 F# 中,它们是用用于匹配的标签定义的。
这使您可以使用具有多个相同类型案例的 sum 类型。例如:

type ShoeSize = 
    | EU of double
    | UK of double
    | US of double

【讨论】:

    【解决方案2】:

    C++20 有一个 concept 的概念,它能够以你想要的方式约束模板参数,等等。这在语言中引入了一些可以使用各种技术近似的东西,在这里描述它们似乎超出了范围。

    【讨论】:

      【解决方案3】:

      TypeScript 让你更灵活一点;例如,您可以指定多个允许的类型。

      不,你不能; number | string 是单一类型,称为联合类型。您可以传递numberstring,因为它们都是number | string 的子类型。但你也可以传递任何number | string

      同样,在第二个示例中,T 不限于numberstring;它可以是number | stringnumberstring 的任何子类型。甚至

      var x = new Foo<123 | "">(123)
      

      123 | "" 又是一个非常普通的 TypeScript 类型。

      Scala 3 将具有联合类型;有a discussion of union types for Kotlin,但你可以看到团队不感兴趣。对于 C#,similarly

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-04
        • 2015-07-14
        • 2019-07-24
        • 2021-03-12
        • 2017-09-14
        • 2010-12-05
        相关资源
        最近更新 更多