[타입시스템 18] 매핑된 타입으로 값 동기화
2022. 7. 21. 08:20ㆍ책/이펙티브 타입스크립트
제목만 보면 뭔소리여 싶을 것이다. 결론부터 말하자면 안전한 객체 작성/변경을 위해 타입 체커(특히, 타입 체커가 제공하는 잉여 속성 체크)를 적극 활용하고, 매핑된 타입을 통해 반복을 줄이는 타입 선언을 하자는 뜻이다.
1. 타입 체커/잉여속성 체크
- 앞에서도 얘기했지만 타입을 선언해두면 잉여 속성 체크 또한 가능하다
- 즉, 프로퍼티 작성/추가/제거 과정에서 발생할 수 있는 오류를 잡아준다
- 그리고 타입 선언 과정에서 매핑된 타입을 쓰면 반복을 줄이면서 타입 선언이 가능하다
- 이 두가지 특성을 잘 활용하면 객체를 안전하게 작성/변경할 수 있도록 제약을 걸어둘 수 있다
- 즉, 객체가 가질 값을 타입과 동기화할 수 있다
2. 활용
리액트로 코드를 짜고 있다고 쳐보자. x, y 좌표와 이벤트 핸들러를 props로 받아서 그림을 그리는 작업을 하려고 한다.
x, y좌표가 변경되면 재선언과 리렌더링이 일어나야 겠지만, 이벤트 핸들러는 리렌더링 된다해도 굳이 재선언될 필요가 없을 것이다. 이 상황을 어떻게 처리해야 할까? (useCallback 훅을 쓰면 되긴하겠지만 그건 제외하자)
interface ScatterProps {
// Data
xs: number[];
ys: number[];
// Display
xRange: [number, number];
yRange: [number, number];
// Events
onClick: (x :number, y :number) => void;
}
2.1 fail close 접근법 (보수적 접근법conservative)
- 오류 발생 시 적극적으로 대처하는 방법
- 통상 보안과 관련된 경우 적합하다
onClick 외 값들이 변경되거나 무언가 추가되면 리렌더링한다
하나하나 꼼꼼히 살펴보는 대신 리렌더링이 너무 많이 발생할 수도 있다
function shouldUpdate(oldProps :ScatterProps, newProps :ScatterProps) {
// type k = xs | ys | xRange | yRange | onClick;
let k :keyof ScatterProps;
for (k in oldProps) {
// 교체된 prop이 onClick이 아니라면 update필요
if (k !== 'onClick') return true;
}
// 그게 아니라면 update 불필요
return false;
}
2.2 fail open 접근법
- 오류 발생 시 소극적으로 대처하는 방법
- 기능상 큰 무리가 없고 사용성이 중요한 곳에 쓰인다
딱 필요하다고 생각되는 것만 비교하므로 간단하다
다만 진짜 리렌더링이 필요한 상황에서 누락이 발생한다면
문제는 더 커진다
function shouldUpdate(oldProps :ScatterProps, newProps :ScatterProps) {
// x, y좌표나 그 외 값들에 변동사항이 생기면 update필요
// onClick은 비교대상에서 제외
return (
oldProps.xs !== newProps.xs ||
oldProps.ys !== newProps.ys ||
oldProps.xRange !== newProps.xRange ||
oldProps.yRange !== newProps.yRange
);
}
2.3 매핑된 타입과 타입 체커 활용법
- 위 예시에서 본 방법들은 저마다의 문제점이 있다
- fali close : 어떤 값이 리렌더링의 기준이 되는지 알고 싶다면 함수 내부를 들여다봐야 한다
- fail open : interface의 프로퍼티가 변경되면 필요에 따라 함수를 뜯어 고쳐야 한다(근데 만약 코드짜다 까먹으면?) - 이를 해결하기 위해 아래 그림과 같은 방법(즉, 매핑된 타입과 타입 체커 활용)을 사용할 수 있다
위 그림처럼 만들면 Update Criteria에서 타입체커의 잉여 속성 체크 덕분에 누락이 발생할 이유도 없고, 업데이트 함수 또한 업데이트 목록을 빠뜨릴 염려가 없어진다. 즉, 매핑된 타입으로 업데이트 목록 값을 '동기화' 한 것.
'책 > 이펙티브 타입스크립트' 카테고리의 다른 글
[타입추론 20] 다른 타입엔 다른 변수를 (0) | 2022.07.22 |
---|---|
[타입추론 19] 장황한 코드 방지 (0) | 2022.07.22 |
[타입시스템 17] readony 변경 방지 (0) | 2022.07.20 |
[타입시스템 15] 인덱스 시그니처 (0) | 2022.07.19 |
[타입시스템 14] 반복 줄이기(타입연산, 제네릭) (0) | 2022.07.19 |