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 Tany와 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...