타입스크립트 #1 #2

세나정·2023년 2월 8일
1
post-thumbnail

타입스크립트의 이유?

타입스크립트는 차세대의 웹, 앱, 모바일 앱, NodeJS 프로젝트, IoT 기기를 뒷받침할 언어

흔히 발생하는 실수를 방지하고, 자신과 미래의 개발자들에게 문서화를 제공, 리팩터링을 쉽게, 단위 테스트의 숫자를 반으로 줄임으로 더 안전한 프로그램을 구현할 수 있도록 보장

타입 안전성(type safety) - 타입을 이용해 프로그램이 유효하지 않은 작업을 수행하지 않도록 방지

유효하지 않는 동작의 예시

  • 숫자와 리스트의 곱
  • 객체 리스트를 인수로 받는 함수에 문자열 리스트를 인수로 전달해 호출
  • 객체에 존재하지 않는 멤버 함수 호출
  • 최근 다른 곳으로 이동된 모듈 임포트

자바스크립트의 예시

3 + [] // 문자열 "3"

let obj = {} 
obj.foo // undefined

function a(b) {
	return b/2
}
a("z")  // NaN 

이 처럼 명백하게 잘못된 코드도 자바스크립트는 예외를 던지지 않고 최선을 다 한다.
여기에서, 자바스크립트가 더 이상 유효하지 않은 연산을 조용히 넘어가지 않고 예외를 발생시킨다면?

3 + [] // 에러 : 정말 숫자의 배열을 더하는가?

let obj = {} 
obj.foo // 에러 : obj에 "foo" 프로퍼티를 정의하지 않음

function a(b) {
	return b/2
}
a("z")  // 에러: "a"는 숫자를 인수로 받는 함수인데 문자열을 전달함

자바스크립트는 정확히 언제 실수를 했다고 알려주는가? 바로 '프로그램을 실행할 때'

브라우저로 프로그램을 실행하거나 웹사이트에 사용자가 방문하거나 단위 테스트를 실행하면 프로그램이 동작한다.

타입스크립트가 에러를 알려준다는 사실보다 더욱 좋은 것은 에러를 알려주는 시점이다.

개발자가 편집기에 '코드를 입력하는 순간' 에러 메세지를 발생

이렇게 된다면, 개발자는 프로그램을 구상할 때 타입수준으로 먼저 생각하고 값 수준으로 생각하게 될 것이다.

컴파일러

프로그램이 실행되는 순서
1. 프로그램이 AST (Abstract Syntax Tree, 추상문법트리)로 파싱된다. (AST는 공백, 주석을 완전히 무시)
2. AST가 바이트 코드로 컴파일된다.
3. 런타임이 바이트코드를 평가한다.

타입스크립트가 다른 언어와 다른 점은 컴파일러가 코드를 바이트코드 대신 자바스크립트 코드로 변환한다는 점이다.

이후로는 Node.js, 브라우저에서 실행할 수 있다.

타입스크립트 컴파일러는 AST를 만들어 결과 코드를 내놓기 전에 타입 확인을 가진다

타입 검사기 (Type Checker)
코드의 타입 안전성을 검증하는 특별한 프로그램

TS (TSC가 수행)
1. 타입스크립트 소스 -> 타입스크립트 AST
2. 타입 검사기가 AST를 확인
3. 타입스크립트 AST -> 자바스크립트 소스

JS (브라우저, NodeJS, 자바스크립트 엔진 같은 자바스크립트 런타임이 수행)
4. 자바스크립트 소스 -> 자바스크립트 AST
5. AST -> 바이트 코드
6. 런타임이 바이트 코드를 평가

과정 1~2에서는 소스 코드에 사용된 타입을 이용
과정 3에서는 이용하지 않음 즉, TSC가 타입스크립트 코드를 자바스크립트 코드로 컴파일 할 때는 개발자가 사용한 타입을 확인하지 않음

개발자가 코드에 기입한 타입 정보는 최종적으로 만들어지는 프로그램에 아무런 영향을 주지 않고 단지 타입을 확인하는 데만 쓰인다는 뜻이다.
즉, 마음대로 타입을 바꾸고 개선하고 실험해도 기존의 응용프로그램이 망가질 염려가 없음

타입 시스템

타입시스템 (Type System)
타입 검사기가 프로그램에 타입을 할당하는 데 사용하는 규칙 집합

명시적 타입시스템 | 자동 추론 타입시스템
타입스크립트는 두 가지 시스템 모두의 영향을 받음
즉, 개발자는 타입을 명시하거나 타입스크립트가 추론하도록 하는 방식 중에서 선택 가능
명시적 타입 시스템을 이용하고 싶으면 어노테이션을 활용하면 됨

명시적

let a : number = 1
let b string = 'hello'
let c = [true, false] 

자동 추론

let a = 1 
let b = 'hello'
let c = [true, false] 

타임스크립트 vs 자바스크립트

타입은 어떻게 결정되는가?

동적 타임 바인딩이란 자바스크립트가 프로그램을 실행해야만 특정 데이터의 타입을 알 수 있음을 의미 즉, 자바스크립트는 프로그램을 실행하기 전에는 타입을 알 수 없다.

타입스크립트는 점진적으로 타입을 확인하는 언어이므로 타입스크립트는 컴파일 타임에 프로그램의 모든 타임을 알고 있을 때 최상의 결과를 보여줄 수 있지만, 프로그램을 컴파일 하는 데 반드시 모든 타입을 알아야하는 것은 아님

타입을 지정하지 않은 프로그램이라도 그중 일부 타입을 추론해서 오류를 검출할 순 있지만, 모든 타입을 알지 못하는 상황에선 많은 오류가 사용자에게 그대로 노출될 수 있다.

점진적 타입 확인은 타입을 지정하지 않은 기존 자바스크립트 코드를 타입을 사용하는 타입스크립트로 마이그레이션 할 때 유용

코드를 마이그레이션하는 상황이 아니라면 모든 코드의 타입을 컴파일 타임에 지정하는 것을 목표로 해야함

자동으로 타입이 변환되는가?

자바스크립트는 약한 타입의 언어이므로 숫자와 배열을 더하는 유효하지 않은 연산 같은 것을 수행하면 다양한 규칙을 적용해가 개발자가 정말 의도한 바를 알아내려 노력하고, 주어진 정보로 최상위 결과를 도출

자바스크립트

3 + [1] // "31"로 평가
(3).toString() + [1].toString() // "31"로 평가

타입스크립트

3 + [1] // 에러 TS2365 : `+` 연산자를 '3'과 'number[]'타입에 적용할 수 없음
(3).toString() + [1].toString() // "31"로 평가

올바르지 않아 보이는 연산을 수행하면 타입스크립트카 바로 그 부분을 지적하며, 의도를 명시해야 타입스크립트의 지적을 무사히 통과할 수 있다.

자바스크립트가 제공하는 이런 종류의 암묵적 변환 떄문에 문제의 원인을 추적하기 어렵고 이는 자바스크립트의 큰 골칫거리임

언제 타입을 검사하는가?

타입스크립트는 컴파일 타임에 코드의 타입을 확인하기 때문에 코드를 실행하지 않고도 이전 예제 코드에 에러가 있음을 바로 알 수 있음

코드가 컴파일 되지 않는다는 사실은 개발자가 실수를 저질렀음을 뜻하므로 코드를 실행하기 전에 실수를 바로 잡을 수 있는 좋은 기회가 된다.

에러는 언제 검출되는가?

자바스크립트는 런타임에 예외를 던지거나 암묵적 형변환을 수행함 즉, 프로그램을 실행해야만 어떤 문제가 있음을 확인
타입스크립트는 컴파일 타임에 문법에러와 타입 관련 에러를 모두 검출

하지만, 스택 오버플로우, 네트워크 연결 끊김, 잘못된 사용자 입력 등 타입스크립트가 컴파일 타임에 검출할 수 없는 런타임 예외도 많다.

결론은 자바스크립트가 런타임 에러로 발생했을 때 많은 에러를 타입스크립트는 컴파일 타임에 검출할 수 있다는 게 핵심이다.

tsconfig.json

모든 타입스크립트 프로젝트에는 루트 디렉터리에 tsconfig.json 파일이 존재해야만 함
이 파일은 타입스크립트의 프로젝트에서 어떤 파일을 컴파일 하고, 어떤 자바스크립트 버전으로 방출하는지 등을 정의

{ 
	"compilerOptions" : {
		"lib" : ["es2015"]
        "module" : "commonjs",
        "outDir" : "dist",
        "sourceMap" : true,
        "strict" : true,
        "target" : "es2015"
    },
    "include" : [
    	"src"
    ]
}

include : TSC가 타입스크립트 파일을 찾을 디렉터리
lib : TSC가 코드 실행 환경에서 이용할 수 있다고 가정하는 API
module : TSC가 코드를 컴파일할 대상 모듈 시스템
outDir : 생성된 자바스크립트 코드를 출력할 딜게터리
strict : 유효하지 않은 코드를 확인할 때 가능한 한 엄격하게 검사
target : TSC가 코드를 컴파일할 자바스크립트 버전

tslint.json

탭을 사용할지, 공백을 사용할지 등을 결정하는 코딩 스타일 규약
선택사항이지만 일괄된 코딩 스타일을 사용하도록 강력히 권장

profile
기록, 꺼내 쓸 수 있는 즐거움

0개의 댓글