타입스크립트 : 프로젝트를 진행하다 보면 표현하기 힘든 타입을 마주할 때가 있음.
-> 원하는 타입을 정확하게 설정해야 해당 컴포넌ㅌ, 함수의 안정성과 사용성을 높일 수 있음..
but 타입스크립트에서 제공하는 유틸리티 타입만으로는 표현에 한계
.
.
.
리액트 컴포넌트 구현 -> 옵션을 props로 받아 유연한 컴포넌트로 만들기 가능
ex) background-color, size 값을 props로 받아와서 상황에 맞게 구현
스타일 관련 props는 styled-components에 전달 -> styled-components에도 해당 타입을 정확하게 작성해줘야 함...
.
.
.
: 컴포넌트가 더 커지고 styled-components로 만든 컴포넌트가 늘어날수록 중복되는 타입이 많아서 관리해야 하는 포인트들이 늘어남 -> Pick, Omit ( :유틸리티 타입) 잘 활용 -> 코드 간결하게 작성 가능
Pick 유틸리티 타입 활용 -> props에서 필요한 부분만 선택하여 styled-components 컴포넌트의 타입 정의
: 중복된 코드 작성하지 않아도 되고 유지보수를 더욱 편리하게 할 수 있음.
이외에도 상속받는 컴포넌트 혹은 부모 컴포넌트에서 자식 컴포넌트로 넘겨주는 props 등에도 Pick, Omit같은 유틸리티 활용 가능.
타입스크립트에는 서로 다른 2개 이상의 객체를 유니온 타입으로 받을 때 타입 검사가 제대로 되지 않는 이슈 있을 때 -> PickOne (유틸리티 함수) 구현
.
.
.
: 식별할 수 있는 유니온 Disciminated Union은 각 타입에 type이라는 공통된 속성을 추가하여 구분 짓는 방법
type Card = {
type: "card";
card: string;
};
type Account = {
type: "account";
account: string;
}
function withdraw(type: Card | Account) {
...
}
withdraw({ type: "card", card: "hyundai" });
withdraw({ type: "account", account: "hana" });
-> 방지 : PickOne이라는 유틸리티 타입을 구현하여 적용
: 여러 속성 중 하나의 속성만 받는 커스텀 유틸리티 타입을 구현하기 전에 구현해야 하는 타입이 정확히 무엇인지 생각해야함.
{ account: string } | { card: string }
문제) account와 card 속성을 동시에 가진 객체도 허용하는 문제가 있음.
account일 때는 card를 받지 못하고, card일 때는 account를 받지 못하게 하려면 하나의 속성이 들어왔을 때 다른 타입을 옵셔널한 undefined 값으로 지정하는 방법을 생각해 볼 수 있음...
: 옵셔널 + undefined 타입 지정 -> 사용자가 의도적으로 undefined 값을 넣지 않는 이상, 원치 않는 속성에 값을 넣었을 때 타입 에러 발생.
예제가 뭔소린지 진짜 모르겠음
PickOne
: TypeScript에서 객체 타입 중 하나의 속성만 선택하도록 제한하는 유틸리티 타입이야. 여러 속성 중 딱 하나만 필수로 만들고 나머지는 선택적으로 만들 때 유용함.
주로 keyof
와 매핑된 타입을 조합해 구현하며, 선택 가능한 속성들 중 하나만 활성화된 객체를 보장하는 역할.
타입 가드 : 특히 null을 가질 수 있는 Nullable 값의 null 처리는 자주 사용되는 타입 가드 패턴의 하나..!
일반적으로... if문을 사용 -> null 처리 타입 가드 적용
또는
is 키워드 사용 -> NonNullable 타입으로 타입 검사를 위한 유틸 함수 만들어서 사용할 수도 있음.
.
.
.
: 타입스크립틍에서 제공하는 유틸리티 타입으로 제네릭으로 받는 T가 null 또는 undefined일 때, never 또는 T를 반환하는 타입
type NonNullable<T> = T extends null | undefined ? never : T ;
: NonNullable 유틸리티 타입 사용 -> null 또는 undefined를 검사
NonNullable 함수는 매개변수인 value가 null 또는 undefined라면 false를 반환.
is 키워드가 쓰였기 때문에 NonNullable 함수를 사용하는 쪽에서 true가 반환된다면 넘겨준 인자는 null이나 undefined가 아닌 타입으로 타입 가드(타입이 좁혀진다)가 된다.
function NonNullable<T>(value:T):value is NonNullable<T> {
return value !== null && value !==undefined;
}
( 책내용 이해 안되서 따로 찾아서 정리했음... )
Promise.all을 사용할 때 NonNullable을 적용하는 이유 _
: TypeScript의 타입 시스템에서, Promise.all이 반환하는 결과 배열의 요소들이 null이나 undefined가 아님을 보장하기 위해서.
Promise.all은 여러 개의 Promise를 병렬로 실행하고, 모든 Promise가 성공했을 때 결과 배열을 반환.
그런데 반환된 배열의 요소 중 일부가 null 또는 undefined일 가능성이 있다면, 코드에서 이를 매번 확인해야 하니까 불편할 수 있음~
이때...NonNullable 적용 !!!
NonNullable 타입 유틸리티를 쓰면, 특정 타입에서 null과 undefined를 제거할 수 있음 -> 이를 통해 Promise.all 결과 타입을 더 안전하게 만들기 가능
결론 )
NonNullable 사용 -> null과 undefined를 제거가능.
Promise.all로 받은 결과 배열에서 null이나 undefined가 들어올 가능성을 제거해 타입 안정성을 높임.
주의 ) 하지만 실질적으로 null이나 undefined가 들어올 수 없는 상황에서만 안전하게 쓸 수 있으니까, 꼭 타입 정의와 런타임 로직이 일치하는지 확인하기
도서참조 : 우아한 타입스크립트 with 리액트