타입 단언은 타입에 확신이 있을 때 사용하는 타입 지정 방식이다. 나 같은 경우에는 `Unsafe member access ~~` 에러가 발생했을 때 주로 타입 단언을 통해 해결했었다.
타입 단언 사용방법
타입 단언은 기본적으로 as 키워드를 사용하여 정의한다.
const name = '김씨' as string
타입 단언은 타입 에러를 해결하기 위한 좋은 수단이지만 다음 몇가지 사항을 고려해서 사용해야 한다.
타입 단언 사용 시 고려해야할 것들
1. 타입 안정성 : Type Assertion, 즉 타입 단언을 사용하게 되면 Typescript 유형 검사를 우회하게 된다. 따라서 잘못된 타입으로 단언이 되어 있는 경우 런타임 오류가 발생하거나 실제 값과 일치하지 않는 타입 단언으로 인해 사이드 이펙트가 발생할 수 있다.
2. 유지 관리 : 타입 단언을 과도하게 사용하면 코드 유지보수에 악영햘을 줄 수 있다. 코드의 구조나 형태가 변경되는 경우 그에 영향 받는 모든 타입 단언도 변경된 내용에 맞게 함께 업데이트를 해줘야 하기 때문이다.
3. 타입 추론 : Typescript 는 명시적으로 타입을 지정하지 않아도 해당 Type에 대해 추론을 할 수 있다. 가능한 경우에는 유형 추론에 의존함으로써 불필요한 타입 단언을 줄이고 Type의 안정성을 유지하는게 좋다.
4. 복잡한 Type Casting : 정확하게 Type casting이 필요한 중첩 구조의 경우 타입 단언을 사용하면 위험할 수 있다. 복잡한 환경에서 연관된 데이터, 이벤트 구조와 타입 단언이 정확하게 일치하는지 항상 확인해야하기 때문이다.
복잡한 Type Casting을 명확하게 확인할 수 있는 사례를 바로 어제 경험하여 공유하고자 한다.
어제 겪은 에러가 딱 복잡한 Type Casting과 연관된 에러였기에 예시가 궁금하신 분은 아래 부분을 참고하면 되겠다.
그럼 위 포스팅은 중첩된 데이터 구조의 타입 에러를 타입 단언으로 해결한 사례인데, 중첩된 구조이다 보니 타입 단언 역시 복잡해졌다.
복잡한 Type Casting 코드 개선하기 ( aka. 타입 단언 사용하지 않기)
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
const [key, innerKey] = name.split('-'); // name = 'address-city' , 'address-province'
const updatedState = {...state};
(updatedState[key as keyof OverLappedState] as Address)[innerKey as keyof Address] = value
};
위 코드로 타입에러를 해결하기는 했지만 타입 단언이 과도하게 사용되어 데이터 구조, 2가지 타입 중 한 군데에서라도 수정이 발생하면 다시 코드를 작성해야하는 유지보수에 굉장히 불편한 코드임을 한 눈에 볼 수 있다.
개선된 코드
const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
const [key, innerKey] = name.split('-'); // name = 'address-city' , 'address-province'
if(key !== 'address') return;
if(!(innerKey in state[key])) return;
const updatedState = { ...state, [key]: {...state[key], [innerKey]: value} }
};
이렇게 처리할 데이터 구조를 제외하고는 해당 함수에서 사용하지 않도록 작성하면 타입 단언 없이도 원하는 기능을 구현할 수 있다.
이렇게 구현하기 훨씬 가독성도 좋고 유지보수도 편하게 코드를 작성할 수 있었다.
💡 any와 마찬가지로 타입단언 역시 불필요한 경우가 아니면 지양하기로 하자.
개발 잘하는 사람들의 코드를 보고 공부해야하는 이유!!
'TypeScript' 카테고리의 다른 글
TS | insertAdjacentElement 사용하여 자식 element 만들기 (0) | 2022.05.16 |
---|---|
TypeScript | eventListener void 타입 에러 (Feat. onClick) (0) | 2022.02.11 |