[이펙티브 타입스크립트] 1장 타입스크립트 알아보기

Urther·2022년 9월 27일
0

1장 타입스크립트 알아보기

인터프리터(파이썬, 루비와 같이)로 실행되는 것이 아니고, 저수준 언어로 컴파일(자바나 씨언어)되는 것도 아니다. 또 다른 고수준 언어닌 자바스크립트로 컴파일되며, 실행 역시 타입스크립트가 아닌 자바스크립트로 이루어진다. 그렇기 때문에 타입스크립트와 자바스크립트의 관계는 매우 중요하다.

01. 타입스크립트와 자바스크립트의 관계

타입스크립트는 흔히, 자바스크립트의 타입이 추가된 상위 집합이라고 생각한다. 타입스크립트는 자바스크립트의 상위 개념이기 때문에 js 또한 타입스크립트라고 생각할 수 있다. (따라서 자바스크립트 프로그램이 타입스크립트라는 명제는 참이지만, 그 반대는 성립하지 않는다)

자바스크립트를 타입스크립트로 마이그레이션하는 것은 굉장한 이점을 가진다.

const greeting=(who:string)=>{
  console.log(who)
}

위의 코드는 타입스크립트의 유효한 코드이다. 하지만, 자바스크립트를 구동하는 Node 같은 프로그램은 앞의 코드를 실행시키면 오류를 뱉는다. :string은 타입스크립트에서 사용하는 타입 구문이기 때문이다.

prototype 함수 검사

let city="hello world"
console.log(city.toUppercase())

toUppercase() 대신 toUpperCase() 를 사용해야한다고 에러를 내뱉어준다.

객체 검사

const states={
  name:'han',
  age:26,
}

console.log(states.city) //undefined

자바스크립트 같은 경우에는 undefined를 뱉어내서 오류를 검출하기 힘든 점이 존재한다. 그러나 타입스크립트를 사용하면 타입 오류를 잡아낼 수 있다. 그러나 타입스크립트도 한계가 있는 것이 타입과 관련된 오류는 체크할 수 있으나, 오타를 검증할 순 없다.

자바스크립트 런타입 동작을 모델링하는 타입스크립트

자바스크립트에서 허용되지만, 타입스크립트에서는 문제되는 경우가 많다.

타입스크립트는 자바스크립트 런타임 동작을 모델링하는 타입 시스템을 가지고 있기 때문에 런타임 오류를 발생시키는 코드를 찾으려한다. (그러나 모든 오류를 찾아내리라 기대하면 안된다 , 타입 체커를 통과하면서도 런타임 오류를 발생시키는 코드 존재가능)

02 타입스크립트 설정 이해하기

tsconfig.json

{
 "compilerOptions":{
 	"noImplicitAny":true
 }
}

noImplicitAny

  • 변수들이 미리 정의된 타입을 가져야하는지에 대한 여부
    (만약 해제되어있다면 any 타입도 괜찮아짐 => any 를 넣지 않아도 암시적인 any가 된다.)

해제하는 경우는 자바스크립트로 되어있던 기존 프로젝트를 타입스크립트로 전환해야하는 상황에만 사용한다.

strictNullChecks

  • null과 undefined가 모든 타입에서 허용되는지 확인하는 설정이다.
let num:number=null // 만약 strictNullCheck가 해제되어 있다면 오류가 없다고 뜬다.

만약, null 값을 허용하지 않으면 오류가 뜨게 된다. (true 인 경우에)

strict

  • 이 모든 체크를 설정하고 싶다면 strict 설정을 하면 된다. strict 설정은 대부분의 오류들을 잡아낸다.

03. 코드 생성과 타입이 관계 없음을 이해하기

타입스크립트 컴파일러는 두 가지 역할을 수행한다.

  • 최신 타입스크립트/자바스크립트를 브라우저에서 동작할 수 있도록 구버전의 자바스크립트로 트랜스파일한다.
  • 코드의 타입 오류를 체크

두 개는 완전히 독립적이다. 타입스크립트가 자바스크립트로 변환될 때 코드내의 타입에는 영향을 주지 않는다. 자바스크립트의 실행 시점에도 타입은 영향을 미치지 않는다.

타입 오류 있는 코드도 컴파일이 가능하다.

컴파일은 타입 체크와 독립적으로 동작한다.
따라서 타입 오류가 있는 코드도 컴파일이 가능하다.

C언어와 같은 경우는 타입체크와 컴파일이 동시에 이루어진다. 그러나 타입스크립트의 오류는 warning에 불과하다. 문제가 될만한 부분을 알려주지만, 빌드를 멈추진 않는다.

만약, 오류가 있을 경우에 컴파일 하지 않으려면 tsconfig.json 파일에 noEmitOnError를 설정하거나 빌드 도구에 동일하게 적용하면 된다.

런타임에는 타입체크가 불가능하다.

interface Square{
	width:number;
 }
 
 interface Rectangle extends Square{
 	height: number;
 }
 
 type Shape = Square | Rectangle;
 
 function calculateArea(shape:Shape){
 	if(shape insatanceof Rectangle){
    // 실행할 구문
    }
 }

instanceof는 Rectangle(interface)를 지칭하고 있다. 컴파일하고 나면 타입은 없어지는 것이 맞다(컴파일 시에 타입스크립트는 자바스크립트로 변경되기 때문에)

타입 체크와 컴파일이 함께 이루어지는 언어 (C언어, 자바스크립트) 와 달리, 타입스크립트는 오류가 있다고 알려주지만 컴파일을 멈추지는 않는다.

04. 구조적 타이핑에 익숙해지기

자바스크립트는 기본적으로 덕 타이핑 기반입니다.

그 전, 덕타이핑에 대한 정리

덕타이핑이란 ?

“ 새인데 오리처럼 생겼고, 오리처럼 수영하며, 오리처럼 꽥꽥되면 나는 그 새를 오리라하겠다 “

let duck = { id: 1, name: "Duck1"}
console.log(`${duck.id} 는 아이디, ${duck.name}`이 name입니다.)

duck = {id:2} // error
duck = {id:3, name:"Duck2", email:"duck@gmail.com"} //error

처음 객체가 만들어지면 그 형식과 동일한 내용으로 고정이 되는 것이다.

새로운 모양이나, 빠졌다면 동작하지 않는 것이 덕타이핑이라고 한다. (객체의 메서드 존재 여부로 객체의 타입을 결정하는 것)

구조적 타이핑

구조적으로 타입이 일치하면, 맞다고 생각하는 것이다.

interface Vector2D {
  x: number
  y: number
}

function calcLength(v: Vector2D) {
  return Math.sqrt(v.x * v.x + v.y * v.y)
}

interface Vector2DWithName extends Vector2D {
  name: string
}

const a: Vector2DWithName = { name: 'hi', x: 5, y: 10 }
calcLength(a) // works fine

interface Vector2DName {
  name: string
  x: number
  y: number
}

const b: Vector2DName = { name: 'hello', x: 10, y: 10 }
calcLength(b) // works fine, too.

vector2DWithNameVector2DName과는 연관이 없음에도 구조적으로 동일한 타입이라고 인식한다.

profile
이전해요 ☘️ https://mei-zy.tistory.com

0개의 댓글