인자의 타입 지정하기
일반적으로 인자의 타입을 지정한 후, 해당 타입의 값을 호출할 때 넣어주면 해당 타입에 들어있는지 확인 후 타입 에러를 결정한다. 이를 좀 더 편리하게 하기 위해서 객체에 값들을 필드와 값으로 추가해주면 하드코딩을 하지 않을 수 있다.
const ObjectBooks = {
novel: { label: "Novel", code: "N" },
essay: { label: "Essay", code: "E" },
poem: { label: "Poem", code: "P" },
} as const;
const BOOK_KEYS = {
NOVEL: "novel",
ESSAY: "essay",
POEM: "poem",
} as const;
function testObjectGetCode(status: keyof typeof ObjectBooks) {
return ObjectBooks[status].code;
}
console.log(testObjectGetCode(BOOK_KEYS.NOVEL));
console.log(testObjectGetCode("poem"));
as const
as const는 타입스크립트에서 상수 선언으로, 타입 값을 좁히는 데 사용된다.
let foo = "foo"; // string
let foo = "foo" as const; // "foo"
const foo = "foo"; // "foo"
문자나 숫자는 const를 통해서 타입을 확정할 수 있기 때문에 사용할 필요는 없으나, 객체와 배열에서 유용하게 활용할 수 있다. as const를 선언하면 객체는 readOnly로 활용하게 되고, 배열의 경우 요소의 인덱스까지 보존하는 튜플로 보관할 수 있다.
const Colors = {
primary: "blue",
secondary: "green",
};
let color: "blue" | "green";
color = Colors.primary; // string
const ColorsConst = {
primary: "blue",
secondary: "green",
} as const;
let colorConst: "blue" | "green";
colorConst = ColorsConst.primary; // "blue" | "green"
enum으로 타입 안정성 높이기
문자열은 안전하지 않다
그러나 단순히 as const와 keyof typeof를 활용해서 타입을 지정해주는 것은 불안정하다. 아래와같이 문자열을 하드코딩하여 인자로 넘겨주더라도 에러가 생기지 않는다.
const ObjectBooks = {
novel: "N",
essay: "E",
poem: "P",
} as const;
function testObjectGetCode(status: keyof typeof ObjectBooks) {
return ObjectBooks[status];
}
console.log(testObjectGetCode("novel"));
console.log(testObjectGetCode("essay"));
console.log(testObjectGetCode("poem"));
이러한 하드코딩은 오타가 발생할 가능성, 수정 시 전체 코드의 변경 필요, 무일관성 등으로 좋지 않은 방법이다.
네임스페이스를 통한 enum
enum은 C, Java 등의 언어에서도 사용되는 키워드로, 여러 변수들을 하나로 묶어주는 특정 값들의 집합니다. 인자의 타입으로 enum으로 생성한 집합을 넣어주면 enum으로 넣어주지 않으면 에러를 발생시킨다.
enum EnumBooks {
novel = "N",
essay = "E",
poem = "P"
}
function testEnumGetCode(status: EnumBooks) {
...
return status;
}
testEnumGetCode("novel"); // Argument of type '"novel"' is not assignable to parameter of type 'EnumBooks'.
testEnumGetCode(EnumBooks.novel);
enum은 객체로 컴파일 된다
그러나 타입스크립트의 enum을 사용할 때는 주의가 필요하다. 컴파일 과정에서 enum으로 선언한 값들은 자바스크립트의 객체로 변환된다.자바스크립트로 컴파일될 때 추가적인 코드가 생성되므로 유의해야한다.
var EnumBooks;
(function (EnumBooks) {
EnumBooks["novel"] = "N";
EnumBooks["essay"] = "E";
EnumBooks["poem"] = "P";
})(EnumBooks || (EnumBooks = {}));
enum은 트리셰이킹되지 않는다
또한 객체로 변환된 enum은 런타임에서 사용될 수 있기 때문에 rollup, webpack 등의 트리 쉐이킹 도구가 사용하지 않는 코드를 판단하지 못한다.
효율적인 타입 안정성 높이기
as const와 keyof typeof 활용하기
as const와 keyof typeof를 통해 객체와 타입을 지정해주면 enum과 같이 하드코딩을 막을수 있다. 아래에서 AsObjectBooks는 컴파일 과정에서 사라지게 된다.
const AsObjectBooks = {
novel: "N",
essay: "E",
poem: "P"
} as const;
type AsObjectBooks = typeof AsObjectBooks[keyof typeof AsObjectBooks];
function testAsOjectGetCode(status: AsObjectBooks){
...
return status;
}
testAsOjectGetCode("novel"); // Argument of type '"novel"' is not assignable to parameter of type 'AsObjectBooks'.
testAsOjectGetCode(AsObjectBooks.novel);
const enum 활용하기
const enum을 활용하면 컴파일 과정에서 해당 값을 지정해줄 수도 있다. 다만 이는 매핑된 값으로 컴파일된다는 점에서 주의해야한다.
// 컴파일 전
const enum AsObjectBooks {
novel = "N",
essay = "E",
poem = "P"
}
/*
function testAsObjectGetCode(status: AsObjectBooks) {
return status;
}
*/
console.log(AsObjectBooks.novel);
// 컴파일 후(주석 제외)
console.log("N")
각각 타입 지정하기
사실 객체로 보관하는 이상 트리셰이킹을 피할 수는 없다. 따라서 트리셰이킹을 활용하기 위해서는 결국 각각 타입을 export하고 불러오는 타입을 사용해야한다.
Reference
📘 타입스크립트 Enum 타입 정복하기
고급 타입 Enum enum은 C, Java와 같은 언어를 다뤄봤으면 한번쯤 들어보는 흔하게 쓰이는 타입으로 특정 값(상수)들의 집합을 의미한다. 타입스크립트의 튜플 타입이 특정 타입이나 값을 고정하는
inpa.tistory.com
(번역) 타입스크립트에서 'As Const' 이해하기
원글: https://www.omarileon.me/blog/typescript-as-const 새로운 구문인 “상수 어설션(const assertions)“은 TypeScript 3.4에서 도입되었습니다. 이것은 변수가 변경되지 않을 것(immutable)이고 가능한 엄격한 타입을
soobing.github.io