将字符串文字解析为枚举数组

时间:2018-04-25 16:12:23

标签: javascript json typescript json-deserialization

我在API响应中收到以下内容:

{ "roles": [ "ADMIN", "USER" ] }

其中响应​​将始终包含一系列角色(USERPRESENTERORGANIZERADMIN)。

我想将其转换为有效的TypeScript数组(Role[]),其中类型Role的定义如下:

export type Role = 'USER' | 'PRESENTER' | 'ORGANIZER' | 'ADMIN'

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

您的Role类型枚举。它只是一种限于某些值的字符串类型。

您可以将结果转换为Role[],TypeScript会很高兴。这假设传入的数据永远不会有错误值!

const data: {roles: Role[]} = JSON.parse('{"roles": ["ADMIN", "USER"]}');
data.roles // TypeScript knows it is a Role[]

答案 1 :(得分:1)

可以将它转换为你的联合类型:

const apiRoleArray = ["ADMIN", "USER"];
const realRoleArray: Role[] = <Role[]>apiRoleArray;

您可能想要验证其内容,而不仅仅是信任API。 :-)在this question's answers上绘图,您可以使用对象的键创建类型,而不是按字面定义(请参阅accepted answer了解原因):

const roleStrings = {
    USER: "",
    PRESENTER: "",
    ORGANIZER: "",
    ADMIN: ""
};

export type Role = keyof typeof roleStrings;

然后给自己一个验证功能:

const isRole = (s: string): s is Role => {
    return roleStrings.hasOwnProperty(s);
};

然后是一个强大的转换函数,例如:

const rawToRoleArray = (rawArray: string[]): Role[] => {
    return rawArray.map(s => {
        if (!isRole(s)) {
            throw new Error("Invalid Role: " + s);
        }
        return <Role>s;
    });
};

(如果你不单独需要它们,你可以将它们结合起来)

然后使用它:

// Valid
const realRoleArray: Role[] = rawToRoleArray(["ADMIN", "USER"]); 
console.log(realRoleArray);
// Invalid
const realRoleArray2: Role[] = rawToRoleArray(["ADMIN", "FOO"]); 
console.log(realRoleArray2);

Live in the playground | Live on jsFiddle

答案 2 :(得分:0)

如果我知道你想要做什么,那么

enum RoleEnum {
  USER,
  PRESENTER,
  ORGANIZER,
  ADMIN
}

const parseEnum = (name: String): RoleEnum  => RoleEnum[`${name}`]

const parsed: RoleEnum[] = [ 'ADMIN', 'USER' ].map(parseEnum)

console.log(parsed)