[javascript] 객체 배열에 대한 TypeScript 열거 형

다음과 같이 정의 된 열거 형이 있습니다.

export enum GoalProgressMeasurements {
    Percentage = 1,
    Numeric_Target = 2,
    Completed_Tasks = 3,
    Average_Milestone_Progress = 4,
    Not_Measured = 5
}

그러나 아래와 같이 API에서 객체 배열 / 목록으로 표시하고 싶습니다.

[{id: 1, name: 'Percentage'},
 {id: 2, name: 'Numeric Target'},
 {id: 3, name: 'Completed Tasks'},
 {id: 4, name: 'Average Milestone Progress'},
 {id: 5, name: 'Not Measured'}]

이 작업을 수행하는 쉽고 기본 방법이 있습니까? 아니면 열거 형을 int와 문자열로 캐스팅하고 개체를 배열로 빌드하는 함수를 빌드해야합니까?



답변

까다로운 부분은 TypeScript가 방출 된 객체의 열거 형을 ‘이중’매핑하므로 키와 값으로 모두 액세스 할 수 있다는 것입니다.

enum MyEnum {
    Part1 = 0,
    Part2 = 1
}

다음과 같이 방출됩니다.

{
   Part1: 0,
   Part2: 1,
   0: 'Part1',
   1: 'Part2'
}

따라서 매핑하기 전에 먼저 개체를 필터링해야합니다. 그래서 @Diullei의 솔루션은 정답을 가지고 있습니다. 내 구현은 다음과 같습니다.

// Helper
const StringIsNumber = value => isNaN(Number(value)) === false;

// Turn enum into array
function ToArray(enumme) {
    return Object.keys(enumme)
        .filter(StringIsNumber)
        .map(key => enumme[key]);
}

다음과 같이 사용하십시오.

export enum GoalProgressMeasurements {
    Percentage,
    Numeric_Target,
    Completed_Tasks,
    Average_Milestone_Progress,
    Not_Measured
}

console.log(ToArray(GoalProgressMeasurements));


답변

ES8을 사용하는 경우

이 경우에만 완벽하게 작동합니다. 주어진 enum 의 값 배열을 제공합니다 .

enum Colors {
  WHITE = 0,
  BLACK = 1,
  BLUE = 3
}

const colorValueArray = Object.values(Colors); //[ 'WHITE', 'BLACK', 'BLUE', 0, 1, 3 ]

당신은 이렇게 얻을 colorValueArray[ 'WHITE', 'BLACK', 'BLUE', 0, 1, 3 ]입니다. 모든 키는 배열의 전반부에 있고 모든 값은 후반부에 있습니다.

이런 종류의 열거 형도 잘 작동합니다.

enum Operation {
    READ,
    WRITE,
    EXECUTE
}

그러나이 솔루션은 이와 같은 이기종 열거 형 에서는 작동하지 않습니다.

enum BooleanLikeHeterogeneousEnum {
  No = 0,
  Yes = "YES",
}


답변

열거 형은 런타임에 존재하는 실제 개체입니다. 따라서 다음과 같이 매핑을 되돌릴 수 있습니다.

let value = GoalProgressMeasurements.Not_Measured;
console.log(GoalProgressMeasurements[value]);
// => Not_Measured

이를 바탕으로 다음 코드를 사용할 수 있습니다.

export enum GoalProgressMeasurements {
    Percentage = 1,
    Numeric_Target = 2,
    Completed_Tasks = 3,
    Average_Milestone_Progress = 4,
    Not_Measured = 5
}

let map: {id: number; name: string}[] = [];

for(var n in GoalProgressMeasurements) {
    if (typeof GoalProgressMeasurements[n] === 'number') {
        map.push({id: <any>GoalProgressMeasurements[n], name: n});
    }
}

console.log(map);

참조 : https://www.typescriptlang.org/docs/handbook/enums.html


답변

쉬운 솔루션. 다음 함수를 사용하여 Enum을 개체 배열로 변환 할 수 있습니다.

 buildGoalProgressMeasurementsArray(): Object[] {

    return Object.keys(GoalProgressMeasurements)
              .map(key => ({ id: GoalProgressMeasurements[key], name: key }))
 }

밑줄을 제거해야하는 경우 다음과 같이 정규식을 사용할 수 있습니다.

buildGoalProgressMeasurementsArray(): Object[] {

    return Object.keys(GoalProgressMeasurements)
              .map(key => ({ id: GoalProgressMeasurements[key], name: key.replace(/_/g, ' ') }))
 }


답변

나는 사용한다

Object.entries(GoalProgressMeasurement).filter(e => !isNaN(e[0]as any)).map(e => ({ name: e[1], id: e[0] }));

작업을 수행하는 간단한 한 줄.

간단한 3 단계로 작업을 수행합니다
.-를 사용하여 키와 값의 조합을로드합니다 Object.entries.
-숫자가 아닌 항목을 필터링합니다 (typescript가 역방향 조회에 대한 값을 생성하므로).
-그런 다음 원하는 배열 객체에 매핑합니다.


답변

이것은 열거 형 값의 배열을 제공합니다.

 Object.values(myEnum);


답변

class EnumHelpers {

    static getNamesAndValues<T extends number>(e: any) {
        return EnumHelpers.getNames(e).map(n => ({ name: n, value: e[n] as T }));
    }

    static getNames(e: any) {
        return EnumHelpers.getObjValues(e).filter(v => typeof v === 'string') as string[];
    }

    static getValues<T extends number>(e: any) {
        return EnumHelpers.getObjValues(e).filter(v => typeof v === 'number') as T[];
    }

    static getSelectList<T extends number, U>(e: any, stringConverter: (arg: U) => string) {
        const selectList = new Map<T, string>();
        this.getValues(e).forEach(val => selectList.set(val as T, stringConverter(val as unknown as U)));
        return selectList;
    }

    static getSelectListAsArray<T extends number, U>(e: any, stringConverter: (arg: U) => string) {
        return Array.from(this.getSelectList(e, stringConverter), value => ({ value: value[0] as T, presentation: value[1] }));
    }

    private static getObjValues(e: any): (number | string)[] {
        return Object.keys(e).map(k => e[k]);
    }
}