【问题标题】:How get enum-like behavior from array? Typescript如何从数组中获得类似枚举的行为?打字稿
【发布时间】:2020-07-14 07:00:06
【问题描述】:

我有数组:

const someArray = ['one', 'two', 'three'];

我有类型:

type SomeType = 'one' | 'two' | 'three';

如何从someArray 获得SomeType

【问题讨论】:

标签: typescript


【解决方案1】:

我找到了一个更简单的解决方案。

const someArray = ['one', 'two', 'three'] as const;
                                       /* ^------- IMPORTANT!
                                          otherwise it'll just be `string[]` */

type SomeType = typeof someArray[number];  // 'one' | 'two' | 'three'

【讨论】:

    【解决方案2】:

    您可以,但必须将as const 断言应用于someArray

    const someArray = ['one', 'two', 'three'] as const;
                                           /* ^------- IMPORTANT!
                                              otherwise it'll just be `string[]` */
    
    type GetItem<T> = T extends ReadonlyArray<infer I> ? I : never;
    
    type SomeType = GetItem<typeof someArray>;  // 'one' | 'two' | 'three'
    

    【讨论】:

    • 以防万一有人想知道。以上只有通过改变someArray的定义方式才有可能,这在某种意义上是改变了问题的前提。我将我的答案留在这里,因此人们可能会欣赏这样一个事实,即如果您有一个字符串数组类型的变量,实际上无法检索请求的类型。
    【解决方案3】:

    你不能,因为 TypeScript 不是依赖类型的语言。

    TypeScript 与目前几乎所有其他众所周知的静态类型语言一样,可以为值创建类型,但不能从值创建类型。

    所以你可以为你的值创建一个类型:

    const someArray: SomeType[] = ['one', 'two', 'three'];

    但您不能从您的值创建类型:

    type SomeType = infer T for someArray[T] // invented syntax

    只有dependently typed languages 可以做到这一点。不幸的是,这还不是主流。再给它十年,你会听到更多关于这个的消息。

    这可能并不意味着你被卡住了。随着时间的推移,我有很少的时间因为语言不是依赖类型而完全无法使用类型。你应该试着问另一个问题,可能会得到满意的答案。例如,有一些方法可以在运行时使用类型,例如 https://github.com/gcanti/io-ts

    【讨论】:

    • 对于这种情况,在 TS 中实际上是可能的,请参阅我的回答。不过链接的资源很好。
    • 很好,我不知道这个技巧!当然,只有将数组定义为文字常量(如示例)时,它才会起作用。对于运行时定义的数组,获得结果的唯一方法是通过依赖类型,所以我会在这里留下我的答案并支持你的。
    【解决方案4】:

    通过'filter'遍历返回满足条件的元素

    【讨论】:

      猜你喜欢
      • 2019-03-04
      • 2019-09-25
      • 1970-01-01
      • 2016-10-09
      • 1970-01-01
      • 2022-08-03
      • 2020-04-30
      • 2023-04-01
      相关资源
      最近更新 更多