개발/JavaScript, TypeScript

Typescript 타입을 배열로 정의해보자

꾸럭 2021. 12. 21. 07:37

Typescript는 Javascript를 Java, C, Swift, Kotlin처럼 정적 타입으로 쓸 수 있게 해주는 Javascript의 슈퍼셋이다. 빌드가 되면 브라우저 또는 Node.js가 이해할 수 있는 퓨어한 Javascript로 바뀌어 동적 타입인 Javascript의 태생적 한계를 극복하고 Javascript 생태계를 보다 안정적으로 쓸 수 있게 해준다.

 

다음을 살펴보자

let a = 1;
console.log(typeof a); // number

a = 'abc'
console.log(typeof a); // string

Javascript는 이처럼 변수를 선언해서 number 타입을 넣었다가 string 타입을 넣었다가 자유롭게 쓸 수 있다.

이처럼 동적 타입이기 때문에 때로는 변수를 자유자재로 활용할 수 있으나 코드가 복잡하지고 길어지면 숫자를 넣어야 할 곳에 문자를 넣어 예기치 못한 에러가 발생할 수 있으며, 이는 실제 애플리케이션이 돌아가는 런타임에서만 확인할 수 있다.

 

다른 예를 보자

const a = {
    abc: 1,
    bcd: 'aaa',
    efg: ['a', 'b', 'c']
};

a.hij = 'hello';
a.bcd = 3;

기존 a에는 없는 key인 hij를 넣어도 에러가 안나고 자연스럽게 hij라는 key가 생기고 'hello'라는 문자열 값이 들어가게 된다.

또한 기존 bcd는 문자열 타입이었으나 3이라는 숫자 타입을 넣어도 문제가 없이 잘 진행이 된다.

또한 스크린샷처럼 IDE에서 인텔리센스를 통해 hij를 추론하지도 못한다.(물론 IDE에 따라 가능할 수도 있다.)

 

이제 위 예제를 Typescript로 바꿔보자

abc는 number, bcd는 string, efg는 string 배열, hij는 string이나 ?를 찍어서 옵션으로 두었다.

그래서 최초 a를 선언할 때 hij를 넣지 않아도 에러가 나지 않았다.

이후 bcd에 3이라는 number 값을 넣으려고 하니 위와 같이 Type 'number' is not assignable to type 'string'이라는 에러가 떴다.

 

기존 Javascript라면 당연히 에러 없이 패스되는 케이스지만 Typescript에서는 에러가 발생하게 된다.

이처럼 Typescript를 통해 보다 안전하게, 그리고 IDE에서 다양한 도움을 받을 수 있게 되어 개발이 보다 편해진다.

 

그런데 다음과 같은 케이스가 있다.

type ColorType = 'white' | 'red' | 'yellow' | 'green' | 'black' | 'blue';
const color: ColorType = 'green';
const color2: ColorType = 'pink'; // error

이 케이스의 경우 컬러 타입을 사전에 정의하고 이 타입에는 위에 나열한 컬러 문자열 값만 들어가도록 한 것이다.

만약 다음과 같이 color2와 같이 선언한다면 에러가 날 것이다.

 

이제 본론이다.

사용자의 화면에 ColorType에서 정의한 컬러들을 나열해놓고 그 중에서 사용자에게 어떤 컬러를 선호하는지 받는다고 가정하자. 그럼 다음과 같이 colorList를 선언하고 이 배열을 이용해 UI를 멋지게 꾸밀 수 있을 것이다.

type ColorType = 'white' | 'red' | 'yellow' | 'green' | 'black' | 'blue';
const colorList: ColorType[] = ['white', 'red', 'yellow', 'green', 'black', 'blue'];

문제점을 캐치했을 것이다. 바로 똑같은 코드를 반복해서 썼다는 것이다. 프로그래밍에서 이런 케이스는 매우 좋지 않고 컬러값이 추가됐을 때 2군데 이상을 계속 수정해나가야 한다.

 

해결 방법은 다음과 같다.

const COLORS = ['white', 'red', 'yellow', 'green', 'black', 'blue'] as const;

type ColorType = typeof COLORS[number]
const colorList: ColorType[] = [...COLORS]; // ['white', 'red', 'yellow', 'green', 'black', 'blue']
const colorList2: ColorType[] = ['pink']; // error
const COLORS = ['white', 'red', 'yellow', 'green', 'black', 'blue', 'pink'] as const;

type ColorType = typeof COLORS[number]
const colorList: ColorType[] = [...COLORS]; // ['white', 'red', 'yellow', 'green', 'black', 'blue', 'pink']
const colorList2: ColorType[] = ['pink']; // success

COLORS 배열을 한 번 선언함으로써 타입과 리스트 배열 변수를 멋지게 활용할 수 있게 됐다.

또한 기존 타입에 pink를 추가하고자 할 때 COLORS에만 추가를 하면 자연스럽게 타입도 바뀌며, 실제 사용할 때도 문제가 없게 된다.

728x90