interface Car {
title :string
wheelType: string
createDate : string
}
이렇게 Car의 interface가 있을때, type을 다 string으로 해놓은 구조가 있다고 생각해보자.
벌써 어지럽다. 어떤 값을 넣어야 할지 감도 안온다.
type을 구체적으로 작성하는 것은 일종의 아이덴티티를 갖는 것 이다.
그리고 ts를 쓰는 이유중 가장 큰 이유는 개발환경에서 타입을 통한 함수의 의미추론이다.
function getCarListByWheelType(type: string) {
const carList:Car[]=[]
return carList.filter(wheelType === type)
}
이러한 함수가 있다고 해보자,
이걸 쓰려고 type에 마우스 커서를 스리슬쩍 올려보면 string이라고 뜬다.
그럼 이제 이걸 확인하기위해서 정적으로 찾아다니러가야한다. 이건 예시를 위해서 car 저렇게 넣어놨는데, 저 멀리서부터 찾아야 한다면 혹은 기타등등 추가적인 비용이 쓸데 없이 들어간다.
그렇다면, 여기서
interface Car {
title :string
wheelType: WheelType
createDate : Date
}
type WheelType = 'two' | 'four'
function getCarListByWheelType(wheelType: WheelType ) {
const carList:Car[]=[]
return carList.filter(wheelType === type)
}
Car의 interface를 좁힌다면, 그로인해서 wheelType을 정의한다면
마우스 커서 올리는 순간 확 dx가 올라감은 물론이고 에러를 통해서 실수가 발생하지 않게된다.
key를 통해 mapping하는 함수가 있다고 했을때
const mappingByKey = <T,>(arr:T[],key:keyof T):T[keyof T][] => {
return arr.map(item => item[key])
}
const carList : Car[]=[]
mappingByKey(carList,'title')
이렇게 작성하면 mappingByKey의 return되는 type이 (string | Date)[] 형식으로 나타난다. 그래도 이렇게라도 하면 key의 값이 intellisense로 나타나서 만족스럽다. 그래도 좀 더 수정할 방법이 있을까?
const mappingByKey = <T,K extends keyof T>(records:T[],key:K):T[K][] => {
return records.map(record => record[key])
}
이렇게 제네릭을 하나더 추가해주는 방법이다.
typeChallenge를 해보신 분들은 아시겠지만, 이렇게 제네릭을 하나 더 추가해서 쓰는 경우가 되게 많다.
이렇게 string을 줄이는 방법을 통해 꽤 많은 것을 얻을 수 있다.
any를 막 쓰는 것 만큼이나, 광범위한 타입을 쓰는 것이 타입스크립트를 불편하게 쓰는 경우인 것 같다.