item 28
- 유효한 상태만 표현하는 타입을 지정하자.
- 유효한 상태를 표현하는 값만 허용한다면 코드를 작성하기 쉬워지고 타입 체크가 용이해짐.
interface State {
pageText: string;
isLoading: boolean;
error?: string;
}
// 아래와 같이 바꿀 수 있음.
interface RequestPending {
state: 'pending';
}
interface RequestError {
state: 'error';
error: string;
}
interface RequestSuccess {
state: 'ok';
pageText: string;
}
type RequestState = RequestPending | RequestError | RequestSuccess;
interface State {
currentPage: string;
requests: {[page: string]: RequestState};
}
item 29
- 매개 변수 타입은 느슨하게, 반환 타입은 엄격하게 하자.
interface CameraOptions {
center?: LngLat;
zoom?: number;
bearing?: number;
pitch?: number;
}
// 아래와 같이 바꿀 수 있음.
interface Camera {
center: LngLat;
zoom: number;
bearing: number;
pitch: number;
}
interface CameraOptions extends Omit<Partial<Camera>, 'center'> {
center?: LngLatLike;
}
item 30
- 주석, 변수명에 타입을 적지말자.
ageNum
보다 age:number
를 사용하듯이.
- 코드는 바꾼 채 주석을 안바꾸는 등 타입 정보에 모순이 발생할 수 있음.
- 단위가 있는 숫자는 예외임. ex) temperatureC
item 31
- strickNullChecks를 사용하자.
- null 값이 암시적으로 관련되도록 설계하지 말자.
// 버그, 설계 결함이 있는 코드
const extent = (nums: number[]) => {
let min;
let max;
for (const num of nums) {
if (!min) {
min = num;
max = num;
} else {
min = Math.min(min, num);
max = Math.max(max, num); // 이 부분에서 에러
}
}
return [min, max];
};
// min, max가 0인 경우 if문에서 falsy해짐.
// nums 가 빈 배열이라면 [undefined, undefined]를 반환함.
// 개선한 코드
function extent(nums: number[]) {
let result: [number, number] | null = null; for (const num of nums) {
if (!result) {
result = [num, num];
} else {
result = [Math.min(num, result[0]), Math.max(num, result[1])];
}
}
return result;
}
- api 작성 시 반환 타입을 큰 객체로 만들고 반환 타입 전체가 null이거나 null이 아니게 만들어야 함.
// 다음과 같이 두 번의 네트워크 요청이 로드되는 동안 user와 posts 속성은 null이 될 수 있음.
async init(userId: string) { return Promise.all([
async () => this.user = await fetchUser(userId),
async () => this.posts = await fetchPostsForUser(userId) ]);
}
// 개선한 코드
static async init(userId: string): Promise<UserPosts> {
const [user, posts] = await Promise.all([
fetchUser(userId),
fetchPostsForUser(userId)
]);
return new UserPosts(user, posts);
}