4주차 Item 28 ~ 37
유효한 상태와 무효한 상태를 둘 다 표현하는 타입은 혼란을 초래하기 쉽고 오류를 유발하게 된다.
역할을 명확하게 나누어 타입을 분리 처리 해야한다.
따라서 코드가 길어지더라도 유효한 상태만 표현하는 타입을 자향해야 한다.
보통 매개변수 타입은 반환 타입에 비해 범위가 넓은 경향이 있다. 선택적 속성과 유니온 타입은 반환 타입보다 매개변수 타입에 더 일반적이다.
매개변수와 반환 타입의 재사용을 위해서 기본 형태(반환 타입)와 느슨한 형태(매개변수 타입)를 도입하는 것이 좋다.
주석과 변수명에 타입 정보를 적는 것은 피해야한다.
타입 선언이 중복되는 것으로 끝나면 다행이지만 최악의 경우는 타입 정보에 모순이 발생하게 된다.
타입이 명확하지 않은 경우는 변수명에 단위 정보를 포함하는 것을 고려하는 것이 좋다.
한 값의 null 여부가 다른 값의 null 여부에 암시적으로 관련되도록 설계하면 안된다.
API 작성 시에는 반환 타입을 큰 객체로 만들고 반환 타입 전체가 null 이거나 null이 아니게 만들어야 한다.
strictNullChecks는 반드시 필요한 타입스크립트 옵션이다.
interface A {
a: TypeA | TypeB | TypeC
b: TypeD | TypeE | TypeF
}
// 위 유니온 인터페이스 보다
// 아래의 인터페이스의 유니온을 사용하면 속성끼리 잘못된 조합으로 섞이는 경우를 방지할 수 있다.
interface InterA {
a: TypeA
b: TypeD
}
interface InterB {
a: TypeB
b: TypeE
}
interface InterC {
a: TypeC
b: TypeF
}
type A = InterA | InterB | InterC;
문자열을 남발하여 선언된 코드를 피한다. 모든 문자열을 할당할 수 있는 string 타입 보다는 구체적인 타입을 사용하는 것이 좋다.
변수의 범위를 보다 정확하게 표현하고 싶다면 string 타입보다는 문자열 리터럴 타입의 유니온을 사용하면 된다.
객체의 속성이름을 함수 매개변수로 받을때는 string보다 keyof T를 사용하는 것이 좋다.
// 1. 기본
function pluck(records, key) {
return records.map(r => r[key]);
}
// 2. 함수 시그니처 적용
function pluck(records: any[], key: string): any[] {
return records.map(r => r[key]);
}
// 3. 제네릭(정밀성) 적용
function pluck<T>(records: T[], key: string): any[] {
return records.map(r => r[key]); // 오류 발생! (string의 범위가 너무 넓다)
}
// 4. 범위 좁히기
type K = keyof Album; // 타입이 한정적
function pluck<T>(records: T[], key: keyof T): T[keyof T][] {
return records.map(r => r[key]);
} // key의 값으로 하나의 문자열을 넣게되면 반환 타입 | string이 되어 버린다.
// 5. 다수의 제릭 매개변수와 extends를 활용해 더 좁히기
function pluck<T, K extends keyof T>(records: T[], key: K): T[K][] {
return records.map(r => r[key]);
}
타입 안전성에서 복잡한 계층형은 피해야 한다.
정확하게 타입을 모델링할 수 없다면 아에 안해야한다.
any와 unknown를 구별해서 사용해야한다.
unknown : 뭔지 잘 모르겠으니까 너가 타입을 정확히 지정해줘
any : 쓰면 안되는것...ㅎ
가독성을 높이고, 추상화 수준을 올리기 위해서 해당 분야의 용어를 정밀하게 사용해야 한다.
같은 의미에 다른 이름을 붙이면 안된다. 특별한 의미가 있을 때만 용어를 구분해야 한다.
타입스크립트는 구조적 타이핑을 사용하기 때문에, 값을 세밀하게 구분하지 못하는 경우가 있다.
값을 구분하기 위해 공식 명칭이 필요하다면 상표를 붙이는 것을 고려해야 한다.
상표 기법은 타입 시스템에서 동작하지만 런타임에 상표를 검사하는 것과 동일한 효과를 얻을 수 있다.