TS는 JS의 기능들을 제공하며 그 위에 자체 레이어를 추가한 것이며 이 레이어가 TS 타입 시스템이다.
JS는 인터프리터이기 때문에 컴파일 과정에서 원시타입이 전체 코드에 일관되게 할당되어있는지 확인하지 않는다.
TS의 타입시스템은 이를 확인하는 레이어로서 동작한다.
TS는 JS언어를 알고 있기 때문에 변수에 값을 바인딩하면 해당 값을 변수의 타입으로 사용한다.
JS는 flux, mvc 등 다양한 디자인 패턴을 가능하게 하는 동적언어이다.
하지만 오히려 이러한 동적언어의 유연한 특징때문에 몇몇 디자인 패턴은 타입을 제공하는 것이 힘들 수 있는데,
이러한 경우에 TS는 타입이 무엇이 되어야 하는지 명시 가능한 JS 언어의 확장을 지원한다.
interface
를 우선적으로 사용하고 특정 기능이 필요할 때type
을 사용해야 함을 TS에서 강조하고 있다.
이유는 추후 학습으로 체득한 후 수정하도록 하겠다.
아래의 값들은 모두 인터페이스에서 사용할 수 있다.
boolean
bigint
null
number
string
symbol
object
undefined
TS에서 추가한 타입이라고 하는데 아직 개요부분이라 이해하지 못했다.
추후 TS를 사용해보며 체득한 후 다시 정리하려한다.
any
(어떤 타입이든 허용)unknown
(이 타입을 사용하는 사람이 타입이 무엇인지 선언했는가를 확인)never
(이 타입은 발생될 수 없다.)void
(undefined
를 리턴하거나 리턴 값이 없는 함수)위에서는 원시 타입에 대해서만 다루었는데 만약 커스텀 타입이 필요한 경우에 TS의 대표적 코드인 유니온(Union)과 제네릭(Generic)을 사용할 수 있다.
이는 객체들을 조합하여 더 크고 복잡한 객체를 만드는 방법과 유사하다.
유니온은 타입이 여러 타입 중 하나일 수 있음을 선언하는 방법이다.
유니온 타입이 가장 많이 사용되는 사례는 아래와 같이 string
또는 number
타입의 리터럴 집합을 설명하는 경우이다.
type WindowStates = "open" | "closed" | "minimized";
type LockStates = "locked" | "unlocked";
type OddNumbersUnderTen = 1 | 3 | 5 | 7 | 9;
아래와 같이 함수의 파라미터에서 array
또는 string
을 받는 것을 명시할 수도 있다.
function getLength(obj: string | string[]) {
return obj.length;
}
제네릭이란 타입에 변수를 제공하는 방법이다.
일반적으로 배열을 예로 들 수 있다.
제네릭이 없는 배열은 어떤 타입이든 포함할 수 있다.
하지만 제네릭이 있는 배열은 배열 안의 값을 설명할 수 있다.
type StringArray = Array<string>;
type NumberArray = Array<number>;
type ObjectWithNameArray = Array<{ name: string }>;
제네릭을 사용하는 고유 타입을 선언할 수도 있다.
interface Backpack<Type> {
add: (obj: Type) => void;
get: () => Type;
}
// 이 줄은 TypeScript에 `backpack`이라는 상수가 있음을 알리는 지름길이며
// const backpack: Backpack<string>이 어디서 왔는지 신경쓸 필요가 없다.
declare const backpack: Backpack<string>;
// 위에서 Backpack의 변수 부분으로 선언해서, object는 string이다.
const object = backpack.get();
// backpack 변수가 string이므로 add함수에 number를 전달할 수 없다.
// 'number' 형식의 인수는 'string' 형식의 매개 변수에 할당될 수 없습니다.ts(2345)
backpack.add(23);
TS는 타입 검사는 값이 있는 형태에 집중한다.
이를 덕 타이핑(duck typing) 또는 구조적 타이핑이라고 불린다.
객체 또는 클래스에 필요한 모든 속성이 존재한다면, TS는 구현 세부 정보에 관계없이 일치하는 것으로 본다.
interface Point {
x: number;
y: number;
}
function printPoint(p: Point) {
console.log(`${p.x}, ${p.y}`);
}
// "12, 26"를 출력합니다
const point = { x: 12, y: 26 };
printPoint(point);
point
변수는 Point
타입으로 선언된 적이 없지만, TS는 함수내의 타입 검사에서 point
의 형태와 Point
의 형태를 비교한다.
interface Point {
x: number;
y: number;
}
function printPoint(p: Point) {
console.log(`${p.x}, ${p.y}`);
}
const point3 = { x: 12, y: 26, z: 89 };
printPoint(point3); // prints "12, 26"
const rect = { x: 33, y: 3, width: 30, height: 80 };
printPoint(rect); // prints "33, 3"
const color = { hex: '#187ABF' };
// '{ hex: string; }' 형식의 인수는 'Point' 형식의 매개 변수에 할당될 수 없습니다.
// '{ hex: string; }' 형식에 'Point' 형식의 x, y 속성이 없습니다.ts(2345)
printPoint(color);