문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 양쪽 이전 판이전 판다음 판 | 이전 판 | ||
| typescript:enum [2021/10/01 14:20] – 바깥 편집 127.0.0.1 | typescript:enum [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1 | ||
|---|---|---|---|
| 줄 1: | 줄 1: | ||
| + | ====== Enums ====== | ||
| + | ===== Aspects to enums ===== | ||
| + | ==== lookup object ==== | ||
| + | **tsc**는 | ||
| + | <code javascript> | ||
| + | enum Zoo { Cat, Tiger } | ||
| + | </ | ||
| + | 위의 코드를 | ||
| + | <code javascript> | ||
| + | var Zoo; | ||
| + | (function (Zoo){ | ||
| + | Zoo[Zoo[" | ||
| + | Zoo[Zoo[" | ||
| + | )(Zoo || (Zoo{})) | ||
| + | </ | ||
| + | 로 변경한다. | ||
| + | lookup object를 참조한다고 할 수 있다. 이것의 목적은 두 가지입니다 : 문자열에서 숫자로의 매핑 역할을하는 것. Zoo.Cat 또는 Zoo[ ' | ||
| + | |||
| + | ==== declare or ambient ==== | ||
| + | TypeScript에서는 컴파일러가 알아야 할 사항을 " | ||
| + | |||
| + | ==== inlining ==== | ||
| + | 성능 및 코드 크기 때문에 컴파일 할 때 열거 형 멤버에 대한 참조를 숫자로 대체하는 것이 바람직합니다. | ||
| + | <code javascript> | ||
| + | enum Foo { X = 4 } | ||
| + | var y = Foo.X; // emits "var y = 4"; | ||
| + | </ | ||
| + | spec은 이 대체를 호출합니다. 개인적으로 소리가 좋기때문에 " | ||
| + | |||
| + | ===== Enums, how do they work? ===== | ||
| + | 열거 형의 각 측면별로 이것을 분해 해 봅시다. 불행히도이 네 섹션은 다른 모든 섹션의 용어를 참조 할 것 이므로 이 모든 것을 두 번 이상 읽어야합니다. | ||
| + | |||
| + | ==== computed vs non-computed (constant) ==== | ||
| + | Enum 멤버는 계산됨 이거나 아니거나다. 스펙은 비계산 멤버는 // | ||
| + | |||
| + | computed enum 멤버는 컴파일 타임에 값을 알 수 없는 멤버입니다. 물론 계산 된 멤버에 대한 참조는 인라인 될 수 없습니다. 반대로 계산되지 않은 열거 형 멤버는 한 번 컴파일 타임에 알려진 값입니다. 계산되지 않은 멤버에 대한 참조는 항상 인라인됩니다. | ||
| + | |||
| + | 어떤 enum 멤버가 계산되고 계산되지 않는 것입니까? | ||
| + | |||
| + | declare enum (즉, ambient enum)의 멤버는 초기화가 있는 경우에만 상수입니다. 그렇지 않으면 computed이다. declare enum에서 numeric 초기화만 사용할 수 있습니다. | ||
| + | 예: | ||
| + | <code javascript> | ||
| + | declare enum Foo { | ||
| + | X, // computed | ||
| + | Y = 2, // Non-computed | ||
| + | Z, // Computed! Not 3! Careful! | ||
| + | Q = 1 + 1 // Error | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 마지막으로 non-declare non-const enum의 멤버는 항상 계산 된 것으로 간주됩니다. 그러나 컴파일 타임에 계산할 수 있는 경우 해당 초기화식이 상수로 축소됩니다. 이것은 비 const 열거 형 멤버가 결코 인라인되지 않음을 의미합니다 (이 동작은 TypeScript 1.5에서 변경되었으므로 맨 아래의 " | ||
| + | |||
| + | ==== const vs non-const ==== | ||
| + | === const === | ||
| + | enum선언은 '' | ||
| + | <code javascript> | ||
| + | const enum Foo { A = 4 } | ||
| + | var x = Foo.A; // emitted as "var x = 4;", always | ||
| + | </ | ||
| + | const enum은 컴파일 할 때 lookup object를 생성하지 않습니다. 이러한 이유 때문에 위 참조 코드에서 Foo를 참조하는 것은 회원 참조의 일부분을 제외하고는 오류입니다. 런타임에는 Foo 객체가 없습니다. | ||
| + | |||
| + | === non-const === | ||
| + | enum 선언에 const 한정자가없는 경우 멤버가 계산되지 않은 경우에만 멤버에 대한 참조가 인라인됩니다. non-const, non-declare enum은 lookup object를 생성합니다. | ||
| + | |||
| + | ==== declare(ambient) vs non-declare ==== | ||
| + | 중요한 서문은 TypeScript의 '' | ||
| + | |||
| + | === declare === | ||
| + | declare enum은 lookup object를 생성하지 않습니다. 해당 멤버에 대한 참조는 해당 멤버가 계산되면 inline됩니다 (위의 computed vs non-computed 항목 참조). | ||
| + | |||
| + | declare enum에 대한 다른 형식의 참조가 허용된다는 점에 유의해야합니다. 이 코드는 컴파일 오류가 아니지만 런타임에 실패합니다. | ||
| + | <code javascript> | ||
| + | // Note: Assume no other file has actually created a Foo var at runtime | ||
| + | declare enum Foo { Bar } | ||
| + | var s = ' | ||
| + | var b = Foo[s]; // Fails | ||
| + | </ | ||
| + | 이 오류는 " | ||
| + | |||
| + | declare const enum은 --preserveConstEnums (아래 참조)를 제외하고 const enum과 다르지 않습니다. | ||
| + | |||
| + | === non-declare === | ||
| + | non-declare enum은 const가 아닌 경우 lookup object를 생성합니다. inlining은 위에 설명되어 있습니다. | ||
| + | |||
| + | === --preserveConstEnums flag === | ||
| + | 이 플래그는 정확히 한 가지 효과를 냅니다. non-declare const enum은 조회 객체를 방출합니다. 인라인은 영향을받지 않습니다. 이것은 디버깅에 유용합니다. | ||
| + | |||
| + | ==== Common Errors ==== | ||
| + | 가장 일반적인 실수는 일반 enum이나 const enum이 더 적절한 경우 선언 열거 형을 사용하는 것입니다. 일반적인 형식은 다음과 같습니다. | ||
| + | <code javascript> | ||
| + | module MyModule { | ||
| + | // Claiming this enum exists with ' | ||
| + | export declare enum Lies { | ||
| + | Foo = 0, | ||
| + | Bar = 1 | ||
| + | } | ||
| + | var x = Lies.Foo; // Depend on inlining | ||
| + | } | ||
| + | |||
| + | module SomeOtherCode { | ||
| + | // x ends up as ' | ||
| + | import x = MyModule.Lies; | ||
| + | |||
| + | // Try to use lookup object, which ought to exist | ||
| + | // runtime error, canot read property 0 of undefined | ||
| + | console.log(x[x.Foo]); | ||
| + | } | ||
| + | </ | ||
| + | <WRAP center round important 60%> | ||
| + | 기억하십시오 : 실제로 존재하지 않는 것을 '' | ||
| + | </ | ||
| + | |||
| + | ==== Changes in TypeSript ==== | ||
| + | TypeScript 1.4와 1.5 사이에는 non-declare non-const enums의 모든 멤버를 computed로 처리하도록 변경되었습니다 ([[https:// | ||
| + | ===== Enums ===== | ||
| + | enum을 사용하면 이름이 부여된 상수 집합을 정의할 수 있다. | ||
| + | <code javascript> | ||
| + | enum Direction { Up=1, Down, Left, Right } | ||
| + | // Direction.Up은 값 1, Down은 2, Left는 3, Rright는 4를 가진다. | ||
| + | // 1로 초기화되고, | ||
| + | </ | ||
| + | |||
| + | |||
| + | <code javascript> | ||
| + | enum E { | ||
| + | A = getSomeValue(), | ||
| + | B, // error! ' | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== String enums ==== | ||
| + | <code javascript> | ||
| + | enum Direction { | ||
| + | Up = " | ||
| + | Down = " | ||
| + | Left = " | ||
| + | Right = " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Heterogeneous enums ==== | ||
| + | 이론적으로는 가능하지만 어떤 필요성이 있는지는 의문 | ||
| + | <code javascript> | ||
| + | enum BooleanLikeHeterogenousEnum { | ||
| + | No = 0, | ||
| + | Yes = " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Computed and constant members ==== | ||
| + | 각 enum 멤버는 상수 또는 계산됨 중 하나의 값을 가진다. | ||
| + | |||
| + | 멤버가 상수로 간주되는 경우 | ||
| + | * 초기화가 없는 첫번째 멤버( 0으로 대응 ) | ||
| + | * 초기화가 없고 앞의 멤버가 numeric constant인 경우.( +1을 한 값이 된다 ) | ||
| + | * constant enum expression으로 초기화된 경우. <WRAP left round box 100%> | ||
| + | constant enum expression은 compile time에 모두 계산 가능한 TypeScript 수식의 부분집합이다. | ||
| + | - 리터럴 enum 표현식 (기본적으로 문자열 리터럴 또는 숫자 리터럴) | ||
| + | - 이전에 정의 된 상수 열거 형 멤버 (다른 열거 형에서 비롯 될 수 있음)에 대한 참조 | ||
| + | - 괄호 안의 constant enum expression | ||
| + | - 상수 열거 표현식에 적용된 +, -, ~ 단항 연산자 중 하나 | ||
| + | - 피연산자로 상수 enum 표현식이있는 이진 연산자 +, -, *, /, %, <<, >>, >>>, | ||
| + | </ | ||
| + | |||
| + | constant enum expression이 '' | ||
| + | |||
| + | 다른 경우의 모든 enum 멤버는 **computed**로 간주됩니다. | ||
| + | |||
| + | <code javascript> | ||
| + | enum FileAccess { | ||
| + | // constant members | ||
| + | None, | ||
| + | Read = 1 << 1, | ||
| + | Write = 1 << 2, | ||
| + | ReadWrite | ||
| + | // computed member | ||
| + | G = " | ||
| + | } | ||
| + | </ | ||
| + | ==== Enums at runtime ==== | ||
| + | Enums는 런타임에 존재하는 실제 객체이다. | ||
| + | <code javascript> | ||
| + | enum E { | ||
| + | X, Y, Z | ||
| + | } | ||
| + | |||
| + | function f(obj: { X: number }) { | ||
| + | return obj.X; | ||
| + | } | ||
| + | |||
| + | // Works, since ' | ||
| + | f(E); // enum은 함수에 매개변수로 전달될 수 있다. | ||
| + | </ | ||
| + | ==== Enums at compile time ==== | ||
| + | Enums은 런타임에 존재하는 실제 객체이지만 keyof 키워드는 일반적인 객체에서 기대하는 것과 다르게 작동합니다. 대신 keyof typeof를 사용하여 모든 Enum 키를 문자열로 나타내는 Type을 가져옵니다. | ||
| + | |||
| + | <code javascript> | ||
| + | enum LogLevel { | ||
| + | ERROR, WARN, INFO, DEBUG | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * This is equivalent to: | ||
| + | * type LogLevelStrings = ' | ||
| + | */ | ||
| + | type LogLevelStrings = keyof typeof LogLevel; | ||
| + | |||
| + | function printImportant(key: | ||
| + | const num = LogLevel[key]; | ||
| + | if (num <= LogLevel.WARN) { | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | printImportant(' | ||
| + | </ | ||
| + | |||
| + | ==== Reverse mappings ==== | ||
| + | numeric enums 멤버는 구성원에 대한 속성 이름이있는 개체를 만드는 것 외에도 enum 값에서 enum 이름으로 역매핑을 가져옵니다. | ||
| + | <code javascript> | ||
| + | enum Enum { | ||
| + | A | ||
| + | } | ||
| + | let a = Enum.A; | ||
| + | let nameOfA = Enum[a]; // " | ||
| + | </ | ||
| + | |||
| + | **string enums 멤버는 역 매핑을 전혀 생성하지 않는다는 것을 명심하라** | ||
| + | |||
| + | ==== const enum ==== | ||
| + | 대부분의 경우 열거 형은 완벽하게 유효한 솔루션입니다. 그러나 때로는 요구 사항이 더 엄격합니다. enum 값에 액세스 할 때 여분의 생성 된 코드 및 추가 indirection의 비용을 지불하지 않으려면 const 열거 형을 사용할 수 있습니다. Const enum은 enum의 '' | ||
| + | |||
| + | <code javascript> | ||
| + | const enum Enum { | ||
| + | A = 1, | ||
| + | B = A * 2 | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Const enum은 상수 enum 표현식 만 사용할 수 있으며 일반 enum과 달리 컴파일하는 동안 완전히 제거됩니다. Const enum 멤버는 사용되는 곳에 인라인됩니다. const 열거 형은 computed 멤버를 가질 수 없기 때문에 가능합니다. | ||
| + | |||
| + | <code javascript> | ||
| + | let directions = [Directions.Up, | ||
| + | |||
| + | // 이것은 다음과 같은 코드로 생성된다. | ||
| + | var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */]; | ||
| + | </ | ||
| + | https:// | ||
| + | ==== Ambient enums ==== | ||
| + | 앰비언트 열거 형은 이미 존재하는 열거 형의 모양을 설명하는 데 사용됩니다. | ||
| + | <code javascript> | ||
| + | declare enum Enum { | ||
| + | A = 1, | ||
| + | B, | ||
| + | C = 2 | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ambient 과 non-ambient enums의 중요한 차이점 중 하나는 일반 enum에서는 초기화가 없는 멤버는 이전 enum 멤버가 constant로 간주되는 경우 constant로 간주된다는 것입니다. 대조적으로, | ||