231226(화)
🌱 성장일지 8.0
책 행복한 이기주의자(웨인 다이어)
의 내용에 자극받아 시작하는 소박한 성장기록
- 살아있는 꽃과 죽은 꽃은 어떻게 구별하는가?
- 성장하고 있는 것이 살아 있는 것이다.
- 생명의 유일한 증거는 성장이다!
⚛ (8.0)<완전 개편> 그 날의 키워드 중심으로 간단하게 정리하되 매일 꾸준히 작성할 수 있는 공간을 만들어보자.
Typescript - satisfies
회사 코드에 satisfies
라는 코드가 사용되고 있었다. 어디선가 보기는 했던 것 같은데, 내가 느끼기엔 as
의 역할과 비슷한 느낌이라 그냥 지나쳤던 기억이 있다.
일단 공식문서가 최고니까 공식문서를 살펴보자.
satisfies
연산자는 타입스크립트 4.9 버전에 추가된 비교적 따끈따끈한 연산자다.
공식문서 첫 문장이 satisfies
연산자의 등장 이유를 알려준다.
TypeScript developers are often faced with a dilemma: we want to ensure that some expression matches some type, but also want to keep the most specific type of that expression for inference purposes. # 타입스크립트 개발자들은 종종 딜레마에 직면한다: 우리는 어떤 표현식이 어떤 타입과 일치하는지 확인하고 싶지만, 추론 목적으로 그 표현식의 가장 구체적인 타입을 유지하고 싶기도 하다.
먼저 아래 예시를 보자
const palette = { red: [255, 0, 0], green: '#00ff00', bleu: [0, 0, 255], // ^^^^ sacrebleu - we've made a typo! }; // 아래와 같이 각 속성의 값의 type에 따른 내장 메서드를 사용할 수 있다. const redSum = palette.red.join(''); // palette.red: number[] const greenNormalized = palette.green.toUpperCase(); // palette.green: string
그런데 문제는 위의 예시에서는 palette.blue
가 아닌 palette.bleu
로 오타가 났다는 것이다. 이 오타를 잡기 위해서는 Record
를 사용해야 한다.
type Colors = 'red' | 'green' | 'blue'; const palette: Record<Colors, string | number[]> = { red: [255, 0, 0], green: '#00ff00', bleu: [0, 0, 255], // 이제 오타를 잡을 수 있다. }; // 그러나 아래와 같이 각 속성의 값의 type에 따른 내장 메서드를 사용할 수 없다. // 왜냐하면 palette의 속성의 값의 type이 string | number[]이기 때문이다. const redSum = palette.red.join('');
이런 문제를 해결하기 위해 satisfies
연산자가 등장했다.
type Colors = 'red' | 'green' | 'blue'; const palette = { red: [255, 0, 0], green: '#00ff00', bleu: [0, 0, 255], // 오타도 여전히 잡힌다. } satisfies Record<Colors, string | number[]>; // 그리고 아래와 같이 각 속성의 값의 type에 따른 내장 메서드를 사용할 수 있다. const redSum = palette.red.join(''); // palette.red: number[] const greenNormalized = palette.green.toUpperCase(); // palette.green: string
어떻게 보면 as
와 비슷한 느낌이다. 하지만 영어 단어의 의미 그대로 as
는 타입을 강제로 변환하는 것이고, satisfies
는 타입을 만족하는지 확인하는 것이다. as
는 타입을 강제로 변환하고 믿게 하는 것이기 때문에, any
와 같이 가능하면 사용을 지양해야한다.(타입 검사를 무력화시키는 것이기 때문이다.)
📝 회고
오호... satisfies
연산자에 대해서 좀더 알게 되었다. 이를 얼마나 잘 활용할 수 있을까는 아직 조금 의문이지만, 일단은 Record
를 사용할 때 satisfies
를 사용하면 좋을 것 같다.
(추가 푸념) 아흐 회사 다니면서 어떻게든 공부한 내용을 매일 남기려고 하니 정말 쉽지 않다. 아직 제대로 이 패턴을 내 것으로 만들지 못한 것 같다. 얼른 패턴에 적응해서 시간을 효율적으로 쓸 수 있도록 하자!