[타입추론 19] 장황한 코드 방지
2022. 7. 22. 00:44ㆍ책/이펙티브 타입스크립트
TS는 생각보다 훨씬 타입을 잘 추론한다. 따라서 많은 타입 구문은 불필요하며 비생산적이다.
1. 타입 선언에 대하여
- 타입스크립트가 자체적으로 타입을 추론할 수 있다면 타입 구문을 작성하지 않는게 좋다
- 이상적인 타입스크립트 코드는 함수/메서드 시그니처에 타입 구문을 포함하지만, 함수 내에서 생성된 지역 변수에는 타입 구문을 넣지 않는다.
// 'x', 'y'를 보고 string 타입을 생각했겠지만
// 더 정확히 말하면 리터럴 타입에 가깝다
// 그리고 TS가 이를 훨씬 더 잘 추론해낸다
const axis1 :string = 'x';
const axis2 = 'y';
interface Product {
id :string;
name :string;
price :number;
}
// 매개변수의 타입이 지정돼있다면
// 비구조화 할당문 만으로도
// TS는 지역 변수의 타입들을 전부 추론해낼 수 있다
function logProduct(product :Product) {
const {id, name, price} = product; // 타입선언 불필요
console.log(id, name, price);
}
2. 명시적 타입 구문이 필요한 경우
내부 구현의 오류
2.1 객체 리터럴 정의
- 타입 명시를 해두면 잉여 속성 체크 덕분에 오타나 프로퍼티 작성 오류를 잡는 데 효과적이다
- 변수가 사용되는 순간이 아닌 할당하는 시점에 오류가 표시된다
(만약 잉여 속성 체크가 없었다면 코딩 다 끝나고 런타임 돌리는 시점에 오류가 났을 것임)
interface Product {
id :string;
name :string;
price :number;
}
할당하는 시점에 오류가 표시된다
님 잉여 속성 체크에 걸리셨는데요??
이거 이대로 두고 계속 코드 짤거임?? 실화?
const elem :Product = {
name: 'ABC',
id: '1023i4',
}
2.2 함수의 반환값
- TS가 자체적으로 함수의 반환값을 추론할 수 있는 경우도 있다
- 그러나 반환 타입을 명시하면 아래 이점들이 생긴다
1) 오류의 위치를 제대로 표시해준다 (애초에 잘못 짠 함수인데 나중에 쓸 때 가서 오류나면 빡칠걸?)
2) 반환 타입을 명시하면 함수 자체를 더욱 명확하게 알 수 있다. 즉, 함수 시그니처를 잘 작성해둠으로써 주먹구구식으로 시그니처가 작성되는 것을 방지한다 (TDD와 비슷한 느낌)
3) 명명된 타입을 사용할 수 있다 - 참고로 eslint 규칙 중 no-inferrable-types를 걸어두면 타입 구문이 진짜로 필요한 것인지 확인할 수 있다
// return number[] 라고 잘 추론한다
function cal(elem :number[]) {
return elem.map(v => v*v);
}
1) 오류 표출
아래 getQuote 함수는 number | Promise<any>를 반환한다
const cache: {[ticker :string] :number} = {};
function getQuote(ticker :string) {
// 얘는 number를 반환한다
if (ticker in cache) {
return cache[ticker];
}
// 얘는 Promise를 반환한다
return fetch(`https://example.com/?q=${ticker}`)
.then(response => response.json())
.then(quote => {
cache[ticker] = quote;
return quote;
});
}
만약 캐시된 값이 반환된다면 타입이 promise가 아니므로 then을 쓸 수 없다.
이에 따라 함수를 호출한 코드에서 오류가 발생한다
getQuote('MSFT').then(console)
애초에 코드 자체를 잘못 짰다고 말하는게 더 나을 텐데 굳이?
function getQuote(ticker :string) :Promise<number>{
if (ticker in cache) {
return cache[ticker]; // number형식은 프로미스가 아니다 라고 오류남
}
...
}
3) 명명된 타입
2D 벡터를 입력받아 합성하는 함수
아마 반환 타입이 2D 벡터일 것라고 예상했을 것이다
그러나 TS는 { x: number; y :number; }라고 추론한다
아니 Vector2D로 추론해달라니까 머함;;
interface Vector2D { x :number; y :number; }
function add(a :Vector2D, b :Vector2D) {
return {
x: a.x + b.x,
y: a.y + b.y,
};
}
'책 > 이펙티브 타입스크립트' 카테고리의 다른 글
[타입추론 21] 타입 넓히기 (0) | 2022.07.22 |
---|---|
[타입추론 20] 다른 타입엔 다른 변수를 (0) | 2022.07.22 |
[타입시스템 18] 매핑된 타입으로 값 동기화 (0) | 2022.07.21 |
[타입시스템 17] readony 변경 방지 (0) | 2022.07.20 |
[타입시스템 15] 인덱스 시그니처 (0) | 2022.07.19 |