최근 내가 타입스크립트를 단순 회사의 기술스택이기에 사용하고 있는 건 아닌지에 대해서 의문이 들었다. 사실 타입스크립트를 사용하면 얻게 되는 명확한 이점들이 있는데, 그런 이점들을 줄줄 놓치는(=타입스크립트를 사용하는 이유가 없어지는) 혼란의 코드를 쓰고 있던 건 아닌건지 반성ㅠ...
반성의 기회를 얻은 덕분에 다시 펼쳐본 타입스크립트 핸드북... 타입스크립트 핸드북을 읽으면서, 낯설게 느껴지는 부분들에 대해 정리하고 예시를 직접 작성해본다.
void
변수의 타입으로 쓰일 때에는 undefined와 null을 의미하고, 함수에서는 함수의 반환값으로 쓰인다.
const a : void = null;
const a = (): void => {}
never
never이 함수의 반환값의 타입으로 쓰였을 때에는, 이 함수는 결코 절대 끝까지 끝나지 않는다는 것을 뜻한다.
const a = ():never => {
while true {
// never 안끝남
}
}
interface
배열 선언시 ReadonlyArray<T> 타입을 사용하면 읽기 전용 배열을 생성할 수 있다.
const a: ReadonlyArray<T> = ['red', 'blue', 'green'];
a.push('yellow') // error: Property 'push' does not exist on type 'readonly string[]'.
인터페이스에 정의하지 않은 Props를 추가로 모두 사용하고 싶다면 아래와 같은 방법을 사용할 수 있다.
interface a {
color?: 'red' | 'blue' | 'yeollow';
[propName: string]: any;
}
enum
enum의 key를 꺼내쓰고 싶을 때, 즉 보통의 상황에서 keyof를 사용해야할 때에는 keyof typeof 를 사용해라.
enum Color {
RED,
YELLOW,
GREEN,
BLUE
}
type ColorKeyType = keyof typeof Color; // 'RED' | 'YELLOW' | 'GREEN' | 'BLUE';
리버스 매핑으로 키로 값을 얻고, 값으로 키를 얻을 수 있다. 리버스 매핑은 숫자형 이넘에만 존재하고 문자형 이넘에는 존재하지 않는다. (🤯충격. 문자형 이넘에도 되는 건 줄 알고 있었다. 지금이라도 알아서 개꿀이득 렄키)
enum Answer {
YES,
NO
}
const a = Answer.YES; // 0
const answerKey = Answer[a]; // YES
union type
union type을 사용하는데, union으로 묶이면, 공통된 타입 프로퍼티에만 접근할 수 있다. 명확하게 유니언 타입을 사용하고자 한다면, 타입 type guard를 사용하자.
const a: string | number = 123;
if (a.length) {
...
} // Property 'length' does not exist on type 'number'.
if (typeof a === 'string') {
const num = a.length;
}
generic
제레닉은 타입을 함수의 파라미터처럼 사용하는 것을 의미한다.
const logSth = <T>(sth: T) => {return console.log(sth)}
// function logSth<T>(sth: T): T { ... }
logSth<string>('abc') // 'abc'
logSth<number>(123) // 123
logSth<null>(123) // error: Argument of type '123' is not assignable to parameter of type 'null'.
참고자료
- https://www.typescriptlang.org/docs/
- https://joshua1988.github.io/ts/
추가적 할일
- enum, const enum가 다르게 동작하는데 이거는 추후 따로 정리할 것
- 제네릭 따로 정리할 것