代码之家  ›  专栏  ›  技术社区  ›  Jason Kleban

条件类型的类型脚本枚举类型检查?

  •  0
  • Jason Kleban  · 技术社区  · 6 年前

    我有RESTful服务,它接受枚举值作为数字或字符串,但始终只返回数字。有没有办法打出来?

    这是我想要的,但它在语法上是无效的:

    enum Features {
      "A" = 1,
      "B" = 2,
      "C" = 2
    }
    
    type EnumOrString<T> = T extends enum
      ? T | keyof T
      : T
    
    declare function getData(featureFilter: EnumOrString<Features>[]): Features[]
    

    getData 获取枚举值或枚举键的数组,但仅返回枚举值。

    I also would want to extend this to mapped types like DeepPartial 这样,任何嵌套枚举都可以得到这种处理,而不必具有按请求和响应划分的类型的单独层次结构。

    1 回复  |  直到 6 年前
        1
  •  2
  •   jcalz    6 年前

    我不认为 enum “现在事情是可能的。即使可以,也无法从 Features 类型(即 要素 特征 枚举)到 typeof Features 类型 映射 从键到 特征 元素)不知道 特征 首先。再次说明:类型 Features.B 例如,对字符串文字一无所知 "B" . 只有 功能类型 有这样的财产 {B: Features.B} . 如果要从类型函数转换 特征 Features | keyof typeof Features ,你需要提到 功能类型 明确地。所以即使你有梦想 extends enum 注意,您仍然需要用您关心的映射列表来编写替换代码。对不起的。


    只处理递归部分,以防发生问题,下面是我如何递归处理类型以替换 已知的 具有枚举值和相关键的联合的枚举值:

    enum Features {
      "A" = 1,
      "B" = 2,
      "C" = 2
    }
    type ValueOf<T> = T[keyof T]
    type FeatureKey<T extends Features> =
      Extract<ValueOf<{
        [K in keyof typeof Features]: [K, typeof Features[K]]
      }>, [any, T]>[0]
    
    type DeepFeaturesOrKey<T> =
      T extends Features ? (T | FeatureKey<T>) :
      T extends Array<infer L> ? DeepFeaturesOrKeyArray<L> :
      T extends object ? { [K in keyof T]: DeepFeaturesOrKey<T[K]> } : T
    
    interface DeepFeaturesOrKeyArray<L> extends Array<DeepFeaturesOrKey<L>> { }
    

    如果不指定整个枚举(例如,使用 discriminated union 输入一个特定的枚举值),当然,整个深度任意数组的欺骗,以避免提到可怕的“循环引用”错误消息。 here :

    与联合和交集类型类似,条件类型不允许递归引用自己(但是,允许通过接口类型或对象文本类型间接引用)。

    让我们测试一下:

    interface Foo {
      bar: string,
      baz: Features,
      qux: {
        a: Features[],
        b: boolean
      },
      quux: Features.A,
      quuux: Features.B  
    }
    
    type DeepFeaturesOrKeyFoo = DeepFeaturesOrKey<Foo>
    declare const deepFeaturesOrKeyFoo: DeepFeaturesOrKeyFoo
    deepFeaturesOrKeyFoo.bar; // string
    deepFeaturesOrKeyFoo.baz; // Features | "A" | "B" | "C"
    deepFeaturesOrKeyFoo.qux.a[1];  // Features | "A" | "B" | "C"
    deepFeaturesOrKeyFoo.qux.b; // boolean
    deepFeaturesOrKeyFoo.quux; // Features.A | "A"
    deepFeaturesOrKeyFoo.quuux; // Features.B | "B" | "C" 
    // note that the compiler considers Features.B and Features.C to be the
    // same value, so this becomes Features.B | "B" | "C"
    

    看起来不错。希望有帮助。

    推荐文章