Разбор строковых литералов в массив enum - PullRequest
0 голосов
/ 25 апреля 2018

Я получаю следующее в ответе API:

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

, где ответ всегда будет содержать массив ролей (USER, PRESENTER, ORGANIZER и ADMIN).

Я хочу преобразовать его в действительный массив TypeScript (Role[]), где тип Role определяется следующим образом:

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

Есть идеи?

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Вы можете , просто приведите его к своему типу союза:

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

НО вы, вероятно, хотите проверить его содержимое, а не просто доверять API. :-) Опираясь на ответы на этот вопрос , вы можете создать тип, используя ключи объекта, а не определяя его буквально (см. Здесь принятый ответ , почему):

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 на jsFiddle

0 голосов
/ 25 апреля 2018

Ваш Role тип не перечисление. Это просто тип строки, ограниченный определенными значениями.

Вы можете просто привести результат как Role[], и TypeScript будет счастлив. Это предполагает, что входящие данные никогда не имеют неверного значения!

const data: {roles: Role[]} = JSON.parse('{"roles": ["ADMIN", "USER"]}');
data.roles // TypeScript knows it is a Role[]
0 голосов
/ 25 апреля 2018

Если я вас правильно понял, это то, что вы хотите сделать.

enum RoleEnum {
  USER,
  PRESENTER,
  ORGANIZER,
  ADMIN
}

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

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

console.log(parsed)
...