본문 바로가기

BOOK/Effective Typescript

[이펙티브 타입스크립트| 3장] 타입 추론

전통적으로 '정적 타입', '명시적 타입'이 전통적으로 쓰였다.

타입스크립트는 그에 반해 타입 추론을 적극적으로 수행하는데, 이를 통해 불필요한 코드를 줄일 수 있다.

 

19. 추론 가능한 타입을 사용해 장황한 코드 방지하기

타입스크립트를 사용할 때 모든 타입을 명시적으로 작성하지 않아도 된다.

모든 변수에 타입을 선언하는 것은 비생산적이다.

 

let x:number=12;
// 비효율적

 

위와 같은 코드가 비효율적인 이유는 let으로 선언했을 때 이미 number 타입이 추론되기 때문이기 때문이다. 타입 추론이 된다면 명시적으로 타입 구문을 넣지 않아도 된다. 타입스크립트는 숫자 및 문자열 뿐만 아니라 더 복잡한 객체 또한 추론이 가능하다.

 

 

let과 다르게 const 를 사용하면 더 정확한 타입 추론이 가능하다.

const a=12;

a에는 number 타입이 추론되는 것이 아닌, 12가 추론이 된다. 

 

 

interface Product{
   id:number;
   name:string;
   price:number
}

function logProduct(product:Product){
   const id:number=product.id;
   const name:string=product.name
   const price:number=product.price
}

만약 Product 타입에서 id가 number | string 으로 변경된다면, logProduct의 id는 오류를 내뱉을 것이기 때문에 비효율적이다. 위와 같은 경우는 디스트럭처링(구조분해할당)을 쓰는 것이 좋다.

 

function logProduct(product:Product){
   const {id,name,price} =product;
}

 

타입이 추론될 수 있음에도 여전히 타입을 명시하고 싶은 경우가 있는데, 그 중 하나가 객체 리터럴에 대한 정의다.

 

interface Product{
   id:number;
   name:string;
   price:number
}

const hi:Proudct={
   id:3,
   name:'yes',
   price:2000
 }
 
 
 hi.age=13 // error

 

위와 같이 타입을 명시해준다면, 잉여 속성 체크가 이루어지기 때문에 타입 오류를 잡는데 효과가 있다. (오타도 잉여 속성이라고 판단해서 알려줌) 그리고, 명명된 타입을 사용하기 위해 명시적으로 타입을 정의해줄 수 있다.

 

interface Vector2D {x:number, y:number}
function add(a:Vector2D, b:Vector2D){
    return { x:a.x+b.x , y:a.y+b.y } 
    /* 리턴타입에 대해서 원하는 타입은 Vector2D임에도, 타입 추론시, {x : number, y:number} 된다. */
}

 

20. 다른 타입에는 다른 변수 사용하기

원래 자바스크립트는 암묵적 타입 변환이 가능하기 때문에 아래와 같이 사용이 가능했습니다.

let id="12-34-56" //string 으로 사용
id=12345  //number로 사용

하지만 타입스크립트는 위와 같은 상황이 있을 때 id에 string 타입이 추론되어 타입 에러가 뜹니다.

타입을 바꿀 수 있는 방법은 22장에서 배울 타입의 범위 좁히기가 있습니다.

 

위와 같은 타입 에러를 해결하기 위해 union 타입을 사용할 수 있습니다.

하지만, union 타입을 사용하게 되면 개발을 하며 까다롭게 발생할 수 있기 때문에 다른 변수를 사용하는 것이 좋다.

let id:number|string="12-34-56" //string 으로 사용
id=12345  //number로 사용