왜 TypeScript 의 Enum 에 문제 가 생 겼 습 니까?

7481 단어 TypeScriptEnum
TypeScript 는 많은 정적 컴 파일 언어의 특성 을 도입 했다.예 를 들 어 class(지금 은 JavaScript 의 일부분),interface,generics 와 union types 등 이다.
하지만 오늘 은 집중 적 으로 논의 해 야 할 유형 이 있 습 니 다.이것 이 바로 enum 입 니 다.
많은 정적 언어 에 있어 서 매 거 는 매우 흔히 볼 수 있 는 언어 특성 이다.예 를 들 어 c,c\#,자바 와 swift.매 거 는 당신 이 코드 에서 사용 할 수 있 는 상수 입 니 다.
우 리 는 일주일 의 며칠 을 대표 하기 위해 TypeScript 로 enum 을 새로 만 듭 니 다.

enum DayOfWeek {
  Sunday,
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday
};
이 매 거 진 은 enum 키워드 성명 을 사용 하고 뒤 에는 Day of Week 이름 을 따른다.그런 후에 우 리 는 매 거 진 에서 사용 할 수 있 는 상수 를 정의 한다.
이제 우 리 는 이 매개 변수의 매개 변 수 를 받 아들 여 들 어 오 는 매개 변수 가 주말 인지 아 닌 지 를 판단 하 는 방법 을 정의 합 니 다.

function isItTheWeekend(day: DayOfWeek) {
  switch (day) {
    case DayOfWeek.Sunday:
    case DayOfWeek.Saturday:
      return true;
 
    default:
      return false;
  }
}
마지막 으로 우 리 는 이것 을 사용 할 수 있다.

console.log(isItTheWeekend(DayOfWeek.Monday)); // log: false
프로그램의 마법 문자열 을 없 애 는 데 매우 유용 한 방법 이다.
그러나 일 은 우리 가 생각 하 는 것 처럼 이렇게 간단 하지 않다.다음 코드 호출 은 TypeScript 를 컴 파일 한 후에 무엇 을 얻 을 수 있 습 니까?

console.log(isItTheWeekend(2)); // is this valid?
결 과 를 알 면 깜짝 놀 랄 거 야.이러한 호출 은 TypeScript 규칙 에 부합 되 고 컴 파일 러 도 순조롭게 컴 파일 될 것 입 니 다.
무슨 일이 있 었 죠?
위의 상황 은 TypeScript 의 bug 를 발견 했다 고 생각 할 수 있 습 니 다.사실 TypeScript 는 이렇게 디자인 되 었 습 니 다.
여기에 숫자 매 거 진 을 새로 만 들 었 습 니 다.그리고 TypeScript Playground 에서 컴 파일 된 결과 가 무엇 인지 볼 수 있 습 니 다.

var DayOfWeek;
(function (DayOfWeek) {
    DayOfWeek[DayOfWeek["Sunday"] = 0] = "Sunday";
    DayOfWeek[DayOfWeek["Monday"] = 1] = "Monday";
    DayOfWeek[DayOfWeek["Tuesday"] = 2] = "Tuesday";
    DayOfWeek[DayOfWeek["Wednesday"] = 3] = "Wednesday";
    DayOfWeek[DayOfWeek["Thursday"] = 4] = "Thursday";
    DayOfWeek[DayOfWeek["Friday"] = 5] = "Friday";
    DayOfWeek[DayOfWeek["Saturday"] = 6] = "Saturday";
})(DayOfWeek || (DayOfWeek = {}));
실행 결 과 는:

사실 매 거 진 것 은 자 바스 크 립 트 의 대상 이다.
이 대상 의 속성 은 내 가 정 의 된 매 거 진 상수 에 따라 생 성 되 고 정 의 된 순서에 따라 해당 하 는 숫자(순서,Sunday 는 0,Saturday 는 6)를 생 성 하 는 것 이다.이 대상 에 도 키 로 서 상수 문자열 을 값 으로 하 는 속성 이 있 습 니 다.
따라서 우 리 는 위의 방법 에 숫자 를 전달 하고 숫자 는 해당 하 는 매 거 진 값 에 투사 할 수 있다.매 거 는 숫자 상수 이자 문자열 상수 이다.
언제
만약 하나의 방법 이 매 거 진 유형의 인 자 를 받 아들 이지 만,임의의 숫자 는 컴 파일 을 통과 할 수 있다 면.이러한 결 과 는 분명히 TypeScript 가 구축 한 유형 안전 체 계 를 파괴 했다.이거 언제 쓸 수 있 을까요?
만약 에 서비스 가 JSON 문자열 로 돌아간다 고 가정 하면 이 직렬 모델 을 만 들 고 싶 습 니 다.해당 하 는 속성 은 매 거 진 것 입 니 다.
당신 의 데이터베이스 에 저 장 된 것 은 숫자 입 니 다.TypeScript 매 거 진 을 정의 하면 이 문 제 를 쉽게 해결 할 수 있 습 니 다.

const day: DayOfWeek = 3;
값 을 할당 할 때 실행 되 는 디 스 플레이 형식 변환 은 숫자 를 매 거 진 대응 상수 로 변환 합 니 다.즉,우리 가 코드 에서 이 매 거 진 것 을 사용 하면 코드 를 더욱 쉽게 읽 을 수 있다 는 것 이다.
매 거 진 숫자 를 제어 하 다
매 거 진 구성원 에 대응 하 는 숫자 는 매 거 진 상수 정의 순서에 따라 생 성 된다.그럼 우 리 는 이 숫자의 값 을 제어 할 수 있 습 니까?네,괜찮아 요.

enum FileState {
  Read = 1,
  Write = 2
}
파일 의 가능 한 상 태 를 설명 하 는 매 거 진 일 뿐 입 니 다.
그것 은 읽 을 수도 있 고 쓰기 상태 일 수도 있 습 니 다.우리 가 보 여 준 정 의 는 매 거 진 값 입 니 다.정 의 를 표시 하기 때문에 어떤 값 이 합 리 적 인지 명확 하 다.
비트 값
하지만 또 다른 상황 은 유용 하 다.비트 값(Bit).
이 FileState 매 거 진 을 다시 한 번 살 펴 보고 새로운 매 거 진 값 ReadWrite 를 추가 합 니 다.

enum FileState {
  Read = 1,
  Write = 2,
  ReadWrite = 3
}
그 다음 에 이 유형의 인 자 를 받 아들 이 는 방법 이 있다 고 가정 합 니 다.

const file = await getFile("/path/to/file", FileState.Read | FileState.Write);
우 리 는 FileState 에서|조작 부 호 를 사용 했다.이렇게 하면 우 리 는 비트 연산 을 사용 하여 새로운 매 거 진 값 을 얻 을 수 있다.이 예 에서 3,ReadWrite 의 값 입 니 다.
사실 우 리 는 좀 더 분명하게 쓸 수 있다.

enum FileState {
  Read = 1,
  Write = 2,
  ReadWrite = Read | Write
}
이 ReadWrite 의 값 은 죽은 것 이 아니 라 비트 연산 으로 얻 은 것 이다.
하지만 이렇게 매 거 진 을 사용 할 때 는 더욱 조심해 야 한다.
아래 의 매 거:

enum Foo {
  A = 1,
  B = 2,
  C = 3,
  D = 4,
  E = 5
}
E(또는 5)를 얻 으 려 면 비트 연산 을 할 수 있 습 니까?Foo.A|Foo.D or Foo.B|Foo.C?
따라서 매 거 진 값 으로 비트 연산 을 하려 면 이 값 을 어떻게 얻 는 지 명확 하 게 해 야 한다.
제어 색인
일반적으로 매 거 진 값 마다 기본 값 이 있 습 니 다.필요 하 다 면 이 매 거 진 값 에 도 명확 하 게 할당 할 수 있다.또한 어떤 부분 에 매 거 진 할당 도 할 수 있다.

enum DayOfWeek {
  Sunday,
  Monday,
  Tuesday,
  Wednesday = 10,
  Thursday,
  Friday,
  Saturday
}
앞의 몇 개의 값 은 위치 에 따라 값 을 부여 합 니 다.Sunday 에서 TuesDay 까지 는 0 에서 2 입 니 다.그 다음 에 Wednesday 에서 새로운 값 을 주 었 습 니 다.여기 서부 터 모든 값 이 1 씩 증가 하면 문제 가 발생 할 수 있 습 니 다.

enum DayOfWeek {
  Sunday,
  Monday,
  Tuesday,
  Wednesday = 10,
  Thursday = 2,
  Friday,
  Saturday
}
Tuesday 할당 은 2 입 니 다.생 성 된 JavaScript 는 어떤 모양 입 니까?

var DayOfWeek;
(function (DayOfWeek) {
    DayOfWeek[DayOfWeek["Sunday"] = 0] = "Sunday";
    DayOfWeek[DayOfWeek["Monday"] = 1] = "Monday";
    DayOfWeek[DayOfWeek["Tuesday"] = 2] = "Tuesday";
    DayOfWeek[DayOfWeek["Wednesday"] = 10] = "Wednesday";
    DayOfWeek[DayOfWeek["Thursday"] = 2] = "Thursday";
    DayOfWeek[DayOfWeek["Friday"] = 3] = "Friday";
    DayOfWeek[DayOfWeek["Saturday"] = 4] = "Saturday";
})(DayOfWeek || (DayOfWeek = {}));
보아하니 Tuesday 와 Thursday 의 수 치 는 모두 2 인 것 같다.
따라서 표시 할 설정 값 입 니 다.
비 숫자 매 거
지금까지 우 리 는 수치 매 거 만 논 의 했 지만 매 거 진 값 이 꼭 숫자 만 은 아니다.그것 도 모든 상수 나 계산 값 일 수 있다.

enum DayOfWeek {
  Sunday = "Sun",
  Monday = "Mon",
  Tuesday = "Tues",
  Wednesday = "Wed",
  Thursday = "Thurs",
  Friday = "Fri",
  Saturday = "Sat"
}
이 제 는 isIt The Weekend 방법 에 디지털 인 자 를 입 힐 수 없습니다.이 매 거 는 더 이상 숫자 매 거 가 아니다.그러나 어떤 값 이 합 리 적 인지 일일이 알 고 있 기 때문에 우 리 는 임의의 문자열 을 전달 할 수 없다.
이렇게 하면 또 다른 문 제 를 가 져 온다.

const day: DayOfWeek = "Mon";
이러 면 안 돼.
문자열 은 매 거 진 값 을 직접 부여 할 수 없 으 며,표 시 된 형식 변환 이 필요 합 니 다.
const day = "Mon" as DayOfWeek;
다른 값 을 부여 해 주 시 겠 습 니까?사실 여러 종류의 값 을 매 거 할 수 있 습 니 다.

enum Confusing {
  A,
  B = 1,
  C = 1 << 8,
  D = 1 + 2,
  E = "Hello World".length
}
이 예 의 매 거 진 값 은 모두 숫자 다.그러나 이 숫자 값 은 직접 값 을 부여 할 수도 있 고 계산 값 이나 문자열 의 length 속성 일 수도 있 습 니 다.모두 상수 라면 다양한 종류의 값 일 수 있 습 니 다.

enum MoreConfusion {
  A,
  B = 2,
  C = "C"
}
이런 상황 에 서 는 뒤의 데이터 가 어떻게 작 동 하 는 지 이해 하기 어렵다.그 러 니 이런 매 거 를 쓰 지 않 는 것 이 좋다.
결론.
TypeScript 의 매 거 진 은 JavaScript 에 대한 좋 은 보충 이 며,적절하게 사용 하면 매우 유용 할 것 입 니 다.코드 에 존재 하 는 마술 값(magic values)문자열 과 숫자 를 정리 하 는 데 도움 이 될 것 입 니 다.그리고 유형 이 안전 합 니 다.
TypeScript 의 Enum 에 왜 문제 가 생 겼 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 TypeScript Enum 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기