Search
😘

아이템 24. 일관성 있는 별칭 사용

별칭은 TS의 타입 좁히기를 방해하기에 일관성 있게 사용해야 함
비 구조화 할당 사용 시 일관성에 도움이 됨

1. 별칭 사용

객체에 별칭을 만들고 원래 이름 대신 동일하게 사용할 수 있음
// borough.location에 loc이란 별칭 붙임 const borough = { name: 'Brooklyn', location: [40.688, -73.979] } const loc = borough.location // 별칭 loc 조작시 borough.location 값이 변경 loc[0] = 0 console.info(borough.location) // [0, -73,979]
TypeScript
복사

2. 별칭은 타입 좁히기에 영향을 미침

일관성 없는 별칭은 타입 좁히기를 방해
반복되는 부분이 있어 별칭 사용이 필요한 사례
interface Coordinate { x: number y: number } interface BoundingBox { x: [number, number] y: [number, number] } interface Polygon { exterior: Coordinate[] holes: Coordinate[][] bbox?: BoundingBox } function isPointInPolygon(polygon: Polygon, pt: Coordinate) { if (polygon.bbox) { if (pt.x < polygon.bbox.x[0] || pt.x > polygon.bbox.x[1] || pt.y < polygon.bbox.y[1] || pt.y > polygon.bbox.y[1]) { return false } } // ... more complex check }
TypeScript
복사
반복되는 부분 별칭(box) 사용 시 문제 발생 (별칭의 타입은 정제하지 않음)
function isPointInPolygon(polygon: Polygon, pt: Coordinate) { const box = polygon.bbox if (polygon.bbox) { if ( pt.x < box.x[0] || // ~~~ ~~~ Object is possibly 'undefined' pt.x > box.x[1] || // ~~~ ~~~ Object is possibly 'undefined' ) // ... } // ... } function isPointInPolygon(polygon: Polygon, pt: Coordinate) { const box = polygon.bbox polygon.bbox // Type: BoundingBox | undefined box // Type: BoundingBox | undefined if (polygon.bbox) { polygon.bbox // Type: BoundingBox box // Type: BoundingBox | undefined } }
TypeScript
복사
따라서 별칭 사용시 일관적으로 사용해야 함 (객체 비구조화 사용시 가독성에 도움 됨)
// 별칭을 일관적으로 사용 시 문제 사라짐 (별칭 붙인 후 별칭만 일관되게 사용) function isPointInPolygon(polygon: Polygon, pt: Coordinate) { const box = polygon.bbox // 객체 비구조화 사용시 bbox라는 하나의 이름 쉽게 사용 가능 => 가독성 확보 // const { bbox } = polygon if (box) { // ok if (pt.x < box.x[0] || pt.x > box.x[1] || pt.y < box.y[1] || pt.y > box.y[1]) { // ... } } // ... }
TypeScript
복사
별칭은 런타임에도 혼선을 야기할 수 있음
const polygon: Polygon = { exterior: [], holes: [] } function calculatePolygonBbox(polygon: Polygon) { polygon.bbox = { x: [0, 1], y:[2, 3] } } const { bbox } = polygon if (!bbox) { calculatePolygonBbox(polygon) // polygon.bbox 값 채움 console.info(polygon.bbox) // { x: [0, 1], y:[2, 3] } console.info(bbox) // undefined }
TypeScript
복사
TS의 제어 흐름 분석은 객체 속성에 관해서는 주의해야 함
function fn(p: Polygon) { /* ... */ } polygon.bbox // Type is BoundingBox | undefined if (polygon.bbox) { polygon.bbox // Type is BoundingBox fn(polygon) // fn의 동작이 ploygon.bbox 제거 가능성 polygon.bbox // Type is BoundingBox // TS는 함수가 타임 정제 무효화 하지 않는다고 가정 } // 지역변수로 뽑아내서 사용 시 함수 동작에 따른 영향을 막을 수 있음 const { bbox } = polygon polygon.bbox if (polygon.bbox) { polygon.bbox fn(polygon) bbox // Type is BoundingBox | undefined polygon.bbox // Type is BoundingBox }
TypeScript
복사