Tip-04. 주의할 것들
사용하지 말아야 할 것들
열거형(enum)
아래 코드처럼 값으로 숫자가 들어가면 괜찮지만, 숫자 외의 다른 값이 들어가면 의도와 다르게 동작할 수 있다.
enum Flavor {
VANILLA = 0,
CHOCOLATE = 1,
STRAWBERRY = 2,
}
아래와 같은 문자열 열거형은 덕 타이핑
이 아닌 명목적 타이핑
을 사용한다.
enum Flavor {
VANILLA = 'vanilla'
CHOCOLATE = 'chocolate'
STRAWBERRY = 'strawberry'
}
let flavor = Flavor.CHOCOLATE // 타입이 Flavor
flavor = 'strawberry'; // 덕타이핑이면 Flavor에 포함되므로 에러가 안뜨곘지만, 명목적 타이핑이기 때문에 에러가 뜬다.
그리고 무엇보다... Rollup
과 같은 번들러에서 트리쉐이킹이 되지 않는다.
즉, 최적화가 제대로 이루어지지 않는다.enum
대신 union type
이나 const enum
을 사용하자.union type
은 타입스크립트를 쓴다면 수도 없이 쓸테니 const enum의 예제만 작성한다.
가능하면 union type
을 사용하자.
const enum MOBILE_OS {
IOS = 'iOS',
ANDROID = 'Android',
}
const ios = MOBILE_OS.IOS;
매개변수 속성
아래와 같이 사용할 수 있는 것을 매개변수 속성
이라고 한다.
매개변수 속성은 런타임시에 실제로 사용되는 코드이기 때문에 번들될 때 코드가 늘어난다.
게다가 가독성도 그닥인듯... 일관성 있게 클래스 변수를 직접 선언해주자.
class Person {
constructor(public name: string) {}
}
네임스페이스와 트리플 슬래시 임포트
namespace
키워드나 ///
임포트 사용을 자제하자.
둘 다 호환성을 위해 남아 있을 뿐이다. ES2015 스타일의 모듈(import, export)를 사용하자.
(namespace는 라이브러리들 까보면 가끔 보이는데... 트리플 슬래시는 본 적 없는것 같다.)새로 개발하는데 이것들을 쓴다? 아 이건 좀 ㅋㅋㅋ;
namespace foo {
function bar() {}
}
/// <reference path="other.ts"/>
foo.bar();
데코레이터
데코레이터 패턴! 스프링에서 어노테이션
이라는 이름으로 많이 사용해봤던 패턴이다.2020.04.27
일자 기준으로 tc39에 stage 3
에 위치해 있다.(관련 repo 링크)
빠르면 내년, 늦으면 내후년에 표준으로 합류할 가능성이 매우 높지만... 어디까지나 가능성일 뿐이다.
비표준이 될 수도 있으니 일단은 사용을 자제하자.
주의할 것들
객체 순회
덕 타이핑으로 인해 객체를 순회하는 for in
문법이 제대로 먹히지 않는다.
프로토타입 오염이 되어있을 경우 우리가 작성한 속성 외에 다른 값도 순회에 포함될 수도 있기 때문이다.
const obj = {
one: 'uno',
two: 'dos',
three: 'tres',
};
for (const k in obj) {
const v = obj[k]; // 여기서 에러
}
// 에러 메세지
/*
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ one: string; two: string; three: string; }'.
No index signature with a parameter of type 'string' was found on type '{ one: string; two: string; three: string; }'
*/
객체를 순회하며 키 값을 얻고 싶다면, keyof
를 이용해서 키에 정확한 타입을 지정해주거나Object.entries(obj)
와 같이 배열로 만들어줘서 for of
를 사용하자.
const obj = {
one: 'uno',
two: 'dos',
three: 'tres',
};
for (const [k, v] of Object.entries(obj)) {
console.log(k, v);
}
정보를 감추기 위해 private 사용하지 말기
어차피 private은 런타임에서 사라진다. 심지어 컴파일 시점에서도 단언문을 이용하면 접근이 가능하다.
정말로 정보를 감추고 싶으면 클로저
를 사용하자.
개인적인 팁
array.find<T>()
와 같은 함수는 T
타입의 값 혹은 undefined를 반환한다.
만약 find로 값을 찾지 못했을 때 런타임을 종료시켜야 한다면... 매번 예외 처리를 해주어야 할 것이다.
이런것들은 그냥 모듈화해서 사용자 정의 함수로 만들어버리자. 그게 속 편하다.