타입스크립트 설정은 커맨드 라인을 이용하는 것 보다는 tsconfig.json을 사용하는 것이 좋고, noImplicitAny와 strictNullCheck는 true로 설정하는것이 좋다.
최신 타입스크립트/자바스크립트를 브라우저에서 동작할 수 있도록 구버전의 자바스크립트로 트랜스파일 한다.
코드의 타입 오류를 체크한다.
컴파일은 타입 체크가 독립적으로 동작하기 때문에, 타입 오류가 있는 코드도 컴파일이 가능하다.
트랜스파일이라고 했다가 컴파일이라고 해서 헷갈렸는데 여기서의 컴파일은 첫 번째 경우를 말하는 것 같다 ! (compile이라는 용어가 더 큰 범주에 속하게 되고, 그 안에 transpile이라는 개념이 있게 되는거라 틀린 말은 아님)
트랜스파일 : 한 언어로 작성된 소스 코드를 비슷한 수준의 추상화를 가진 다른 언어로 변환
컴파일 : 한 언어로 작성된 소스 코드를 다른 언어로 변환typescript는 transpiler or compiler?
typescript 의 경우는 javascript로 변환되는데, 뭉뚱 그려 많은 사이트에서는 컴파일링 된다고는 하지만, 거의 같은 수준의 추상화 가 되는것이라 더 정확히 말하면 트랜스파일링 된다고 말할 수 있다.
interface Square {
width: number;
}
interface Rectangle extends Square {
height: number;
}
type Shape = Square | Rectangle;
function caculateArea(shape: Shape){
if (shape instanceof Rectangle) {
return shape.width * shape.height;
}
}
⇒ instanceof 체크는 런타임에 일어나지만, Rectangle은 타입이기 때문에 런타임에 아무런 역할을 할 수 없다. instanceof 대신에 in을 사용하여 해결할 수 있다.function caculateArea(shape: Shape){
if ('height' in shape) {
return shape.width * shape.height;
}
}
또 다른 해결법은 런타임에 접근이 가능한 타입 정보를 명시적으로 저장하는 ‘태그’ 기법이 있다.interface Square {
kind: 'square';
width: number;
}
interface Rectangle extends Square {
kind: 'rectangle';
height: number;
}
type Shape = Square | Rectangle;
function caculateArea(shape: Shape){
if (shape.kind === 'rectangle') {
return shape.width * shape.height;
}
}
function asNumber(val: number | string): number {
return val as number;
}
// 변환된 js 코드
function asNumber(val) {
return val
}
변환된 js를 보면 코드에 아무런 정제 과정이 없다. 값을 정제하기 위해서는 런타임의 타입을 체크해야 하고 자바스크립트 연산을 통해 변환을 수행해야 한다.function asNumber(val: number | string): number {
return typeof(val) === 'string' ? Number(val) : val;
}
자바스크립트는 본질적으로 덕 타이핑 기반이다. 만약 어떤 함수의 매개변수 값이 모두 제대로 주어진다면, 그 값이 어떻게 만들어졌는지는 신경 쓰지 않고 사용한다. 타입스크립트는 이를 모델링 하기 위해 구조적 타이핑을 사용한다.
⇒ 구조적 타이핑에 단점으로, 의도하지 않았지만 동일한 타입을 가지는 경우 의도치 않게 동일한 유형으로 간주될 수 있다.
interface Vector2D {
x: number
y: number
}
interface NamedVector {
name: string
x: number
y: number
}
function calculateLength(v: Vector2D) {
return Math.sqrt(v.x * v.x + v.y * v.y)
}
const v: NamedVector = { x: 3, y: 4, name: 'mgh' }
calculateLength(v)
위 예제는 명목적 타입 시스템을 기준으로 Vector2D를 사용하도록 의도한 코드이다. 하지만 구조적 타이핑 언어에서는 전혀 다른 개념으로 이해해야 한다. Vector2D의 속성에 해당하는 값이 값을 넣는 타입에 속성으로 존재하는가 로 이해해야 한다.
타입은 봉인되어 있지 않다. 즉, [함수 매개변수 속성]이 [매개변수타입에 선언된 속성]만 가지고, 다른 속성은 가지지 않을 것이라고 생각해서는 안된다.
⭐️ 구조적 타이핑을 제대로 이해 한다면 오류인 경우와 오류가 아닌 경우의 차이를 알 수 있고, 더욱 견고한 코드를 작성할 수 있다!