이펙티브 타입스크립트 (댄 밴더캄 지음) 를 읽고 정리
📍요약
✅명시적 타입 구문 작성의 수고로움을 덜기 위해 ES6+ 의 다양한 선언형(함수형) 내장 메서드를 사용하는 것이 좋다
(또는 lodash 같은 유틸리티 라이브러리를 사용하거나...)
📍CSV 파싱 예시
- csv 파일을 파싱하는 예제
const csvData =
`번호,제목,내용
1,공지사항,끝
2,상장,대상`;
const rawRows = csvData.split('\n');
const headers = rawRows[0].split(',');
// 타입에러 해결을 위한 row 타입 선언
interface RowType {
[key: string]: any
}
// 절차형 버전
// rows = header 제외한 row
const rows = rawRows.slice(1).map(rowStr => {
const row: RowType = {};
// rowStr = ["1", "공지사항", "끝"]
rowStr.split(',').forEach((val, j) => {
row[headers[j]] = val;
});
return row;
});
// reduce 사용한 선언형 버전 (더 깔끔)
const rows2 = rawRows.slice(1).map(rowStr => {
// 제네릭으로 타이핑
return rowStr.split(",").reduce<{[key: string]: any}>(
// acc cur idx
(row, val, idx) => (row[headers[idx]] = val, row), {}
// 바로 위에서 row가 리턴되는 이유 추측 -> 그냥 최신화를 위해서 리턴해주기?
)
});
타이핑하지 않으면 타입에러가 발생한다
row = {} 의 인덱스 시그니처가 필요하기 때문이다
1️⃣ 절차형 버전에서는 별도의 타입을 선언해줬고,
2️⃣ 선언형 버전에서는 제네릭을 사용했다
⭐타이핑을 위해 했던 방법 대신 Record 유틸리티 타입을 사용할 수도 있다
// 1.
interface RowType {
[key: string]: any
}
// 2.
// <{[key: string]: any}>
// 1번, 2번 대신 Record 유틸리티 타입 활용 가능
Record<string, any>
📍Array.prototype.flat() 메서드 사용할 때 타입은?
flat 메서드는 다차원 배열을 평탄화한다
- 예시
const arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2차원 배열을 예로 들면, 타입 시그니처는 T[][] => T[] 형태이다
- 직접 구현하는것보다 간결하며 별도의 타입 구문도 필요 없어서 편리하다!