null
값 배치하기null
여부가 다른 값의 null
여부에 암시적으로 관련되도록 설계하면 안된다.null
이거나 null
이 아니도록 설계해야 한다.null
이 존재하지 않도록 해야 한다.strictNullChecks
를 설정하면 코드에 많은 오류가 표시되겠지만, null
값과 관련된 문제점을 찾아낼 수 있기 때문에 반드시 설정해야 한다.interface Layer {
layout: FillLayout | LineLayout | PointLayout;
paint: FillPaint | LinePaint | PointPaint;
}
// 아래 형태로 작성하면 잘못된 조합으로 섞이는 경우를 방지할 수 있다.
// 또한 태그드 유니온도 사용하기 용이해진다.
interface FillLayer {
type: 'fill';
layout: FillLayout;
paint: FillPaint;
}
interface LineLayer {
type: 'line';
layout: LineLayout;
paint: LinePaint;
}
interface PointLayer {
type: 'paint';
layout: PointLayout;
paint: PointPaint;
}
type Layer = FillLayer | LineLayer | PointLayer;
string
타입보다 더 구체적인 타입 사용하기string
을 남발하여 선언된 코드는 any
와 다를바가 없다.string
보다 더 구체적인 타입을 사용하는 것이 좋다.keyof T
any
와 unknown
을 구별해서 사용해야 한다.API
또는 데이터 형식에 대한 타입 생성을 고려해야 한다.가독성을 높이고, 추상화 수준을 올리기 위해 타입을 정의할 때 해당 분야의 용어로 정의해야한다.
data
, info
, thing
, item
, object
, entity
같은 범위가 모호한 이름은 피해야한다.TS는 구조적 타이핑을 사용하기 때문에 값을 세밀하게 구분하지 못하는 경우가 있다.
값을 구분하기 위해 공식명칭이 필요하다면 상표(brand
)를 붙이는 것도 고려해야 한다.
type Meters = number & { _brand: 'meters' };
type Seconds = number & { _brand: 'seconds' };
const meters = (m: number) => m as Meters;
const seconds = (s: number) => s as Seconds;
const oneKm = meters(1000); // type is Meters
const oneMin = seconds(60); // type is Seconds
// 하지만 산술 후에는 타입이 `number`로 초기화됨
const tenKm = oneKm * 10; // type is number
const oneHour = oneMin * 60; // type is number
상표 사용법
type AbsolutePath = string & { _brand: 'abs' };
function isAbsolutePath(path: string): path is AbsolutePath {
return path.startsWith('/');
}
function listAbsolutePath(path: AbsolutePath) {}
function useAbsolutePath(path: string) {
if (isAbsolutePath(path)) {
listAbsolutePath(path);
}
// `string`형식의 인수는 `AbsolutePath`형식의 매개변수에 할당될 수 없다.
listAbsolutePath(path);
}
any
타입은 가능한 한 좁은 범위에서만 사용하기any
의 사용 범위를 최소한으로 좁혀야 한다.any
로 지정하면 타입 안정성이 나빠진다.any
타입을 반환하는 건 지양수준이 아니라 엄격하게 금해야 한다.any
대신 @ts-ignore
를 사용하는 것이 좋다.이렇게 사용하는 것 자체에 오류가 있는 코드이긴 하나 예제로서 사용됨
Foo
타입을Bar
를 매개변수로 받는 함수에 전달한다는 것 자체가 말이 안됨
function f1() {
const x = expressionReturningFoo();
// @ts-ignore
processBar(x);
return x;
}
any
를 구체적으로 변형해서 사용하기any
를 사용할 때는 정말 모든 값이 허용되어야만 하는지 아주아주 면밀히 검토해야 함any[]
, { [id: string]: any }
, () => any
...