【问题标题】:Validate user input as a TypeScript enum将用户输入验证为 TypeScript 枚举
【发布时间】:2018-08-12 00:44:34
【问题描述】:

我正在构建一个 TypeScript 模块,该模块将函数导出给可以接受任意字符串输入的用户。我想解析这个输入以产生一个枚举值(如果输入不是有效的枚举值,则返回。)我希望它适用于字符串和数字枚举。

我该怎么做?这是我所拥有的:

enum Foo { A = "A", B = "B" };
enum Bar { A = 0, B };

// Desired Foo[], got any[]
const allFoos = Object.keys(Foo).map(k => Foo[k]);

// Desired Bar[], got any[]
const allBars =
    Object.keys(Bar)
        .filter(k => typeof Bar[k] === "number")
        .map(k => Bar[k]);


function parseFoo(arg: string): Foo {
    if (allFoos.indexOf(arg) === -1) return;
    return arg; // TypeScript should know arg is of type Foo by now.
}

function parseBar(arg: string): Bar {
    if (allBars.indexOf(arg) === -1) return;
    return arg; // TypeScript should know arg is of type Bar by now.
}

这是一个 TypeScript 游乐场链接:

https://www.typescriptlang.org/play/#src=enum%20Foo%20%7B%20A%20%3D%20%22A%22%2C%20B%20%3D%20%22B%22%20%7D%3B%0D%0Aenum%20Bar%20%7B%20A%20%3D%200%2C%20B%20%7D%3B%0D%0A%0D%0A%2F%2F%20Desired%20Foo%5B%5D%2C%20got%20any%5B%5D%0D%0Aconst%20allFoos%20%3D%20Object.keys(Foo).map(k%20%3D%3E%20Foo%5Bk%5D)%3B%0D%0A%0D%0A%2F%2F%20Desired%20Bar%5B%5D%2C%20got%20any%5B%5D%0D%0Aconst%20allBars%20%3D%0D%0A%20%20%20%20Object.keys(Bar)%0D%0A%20%20%20%20%20%20%20%20.filter(k%20%3D%3E%20typeof%20Bar%5Bk%5D%20%3D%3D%3D%20%22number%22)%0D%0A%20%20%20%20%20%20%20%20.map(k%20%3D%3E%20Bar%5Bk%5D)%3B%0D%0A%0D%0A%0D%0Afunction%20parseFoo(arg%3A%20string)%3A%20Foo%20%7B%0D%0A%20%20%20%20if%20(allFoos.indexOf(arg)%20%3D%3D%3D%20-1)%20return%3B%0D%0A%20%20%20%20return%20arg%3B%20%2F%2F%20TypeScript%20should%20know%20arg%20is%20of%20type%20Foo%20by%20now.%0D%0A%7D%0D%0A%0D%0Afunction%20parseBar(arg%3A%20string)%3A%20Bar%20%7B%0D%0A%20%20%20%20if%20(allBars.indexOf(arg)%20%3D%3D%3D%20-1)%20return%3B%0D%0A%20%20%20%20return%20arg%3B%20%2F%2F%20TypeScript%20should%20know%20arg%20is%20of%20type%20Bar%20by%20now.%0D%0A%7D

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我将构建枚举键映射到枚举值:

    const allFoos = mapKeys<Foo>(Foo);
    const allBars = mapKeys<Bar>(Bar);
    
    function mapKeys<T>(enumType: { [key: string]: any }) {
        return  Object.keys(enumType)
            .filter(k => typeof enumType[k] === "string")
            .reduce((map, key) => { 
                map.set(key, enumType[key]);
                return map;
            }, new Map<string, T>())
    }
    
    function parseFoo(arg: string): Foo {
        return allFoos.get(arg);
    }
    
    function parseBar(arg: string): Bar {
        return allBars.get(arg);
    }
    

    【讨论】:

      【解决方案2】:

      这有帮助吗?

      function parseFoo(arg: string): Foo {
          if (allFoos.indexOf(arg) === -1) return;
          return arg as Foo;
      }
      
      function parseBar(arg: string): Bar {
          const argNum = Number(arg);
          if (isNaN(argNum) || allBars.indexOf(argNum) === -1) return;
          return argNum as Bar;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 2012-07-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多