将用户输入验证为TypeScript枚举

时间:2018-03-04 05:14:34

标签: typescript

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

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

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

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

这有帮助吗?

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;
}