TypeScript를 사용하여 개발하면서, 특정 값들의 집합을 타입으로 정의하고 동시에 데이터로도 활용해야 하는 상황이 자주 발생했습니다. 예를 들어, 포켓몬의 능력(abilities)을 정의할 때 단순한 문자열 배열로 선언하면, 해당 배열을 타입으로 활용하기 어렵다는 문제가 있었습니다. 리터럴 타입으로만 정의할 경우, 데이터로는 유연하게 사용할 수 없고, 타입으로만 제한적으로 사용할 수 있었습니다.
const abilities = [
"air-lock", "arena-trap", "battle-armor",
// 기타 등등...
];
위와 같이 단순히 배열로 선언하면, abilities
배열의 각 요소를 타입으로 활용할 때 리터럴 타입으로 인식되지 않아 타입 안전성이 떨어지고, 코드의 유연성이 제한되는 문제가 있었습니다.
이 문제를 해결하기 위해 const Assertion
을 도입하게 되었습니다. const Assertion
을 사용하면, 배열이나 객체를 읽기 전용으로 만들 뿐만 아니라, 각 요소의 리터럴 타입을 고정시킬 수 있습니다. 이를 통해 데이터로도 활용하면서 동시에 타입으로도 사용할 수 있는 구조를 만들 수 있게 되었습니다.
1. const
Assertion 도입 const
Assertion을 사용하여 배열을 선언하면, 배열의 각 요소가 리터럴 타입으로 고정되고, 배열 자체도 읽기 전용으로 변환됩니다.
const abilities = [
"air-lock", "arena-trap", "battle-armor",
// 기타 등등...
] as const;
위와 같이 as const
를 추가함으로써, abilities
배열은 변경 불가능한(readonly) 튜플로 변환되며, 각 요소는 해당 리터럴 타입으로 고정됩니다.
2. 리터럴 타입을 통한 타입 정의 const
Assertion을 통해 생성된 배열을 기반으로 타입을 정의함으로써, 배열의 각 요소를 타입으로 활용할 수 있게 되었습니다.
export type PokemonAbilityTypes = typeof abilities[number];
위 코드에서 PokemonAbilityTypes
는 abilities
배열의 각 요소를 타입으로 추출한 유니언 타입("air-lock" | "arena-trap" | "battle-armor" | ...
)이 됩니다. 이를 통해 포켓몬의 능력을 타입으로 안전하게 사용할 수 있게 되었습니다.
3. 타입과 데이터의 동시 활용 이제 abilities
배열을 데이터로 사용할 뿐만 아니라, PokemonAbilityTypes
타입을 통해 타입 안전성을 확보할 수 있게 되었습니다.
const myAbility: PokemonAbilityTypes = "air-lock"; // 올바른 값
const invalidAbility: PokemonAbilityTypes = "fly"; // 오류 발생
myAbility
는 PokemonAbilityTypes
에 정의된 유효한 값만 할당할 수 있어, 잘못된 값 할당 시 컴파일 타임에 오류를 방지할 수 있습니다.
const
Assertion을 도입한 후 다음과 같은 개선 효과를 얻었습니다:
const
Assertion을 통해 배열이 읽기 전용으로 변환되어, 의도치 않은 데이터 변경을 방지할 수 있었습니다.const Assertion
을 통해 데이터와 타입을 동시에 관리할 수 있는 강력한 방법을 학습하게 되었습니다. 이는 특히 리터럴 타입을 기반으로 한 타입 안전성이 중요한 상황에서 매우 유용합니다.const
Assertion과 같은 TypeScript의 고급 기능을 적절히 활용하여, 코드의 안정성과 효율성을 높일 수 있다는 점을 경험했습니다.