값과 타입은 타입스크립트에서 별도의 네임스페이스에 존재한다.
interface Dog {
name: string;
age: number;
}
const Dog = {name: 'panggu', age: 11};
위 코드에서 interface
로 정의된 Dog
는 타입으로 사용되었고, const
로 정의된 Dog
는 값으로 사용되었다.
다음은 구조 분해 할당을 사용하여 함수를 정의하려고 한 것이다.
type Person = {
name: string;
age: number;
}
function email({ person: Person, subject: string, body: string }) {
// 실패
}
원래 의도는 매개변수에 들어올 수 있는 객체 타입을 제한하는 것이었겠지만, 실제로는 Person
과 string
이 값 공간에 있는 것으로 해석한다.
위 코드를 의도와 같이 작성하려면 아래와 같이 작성할 수 있다.
function email({ person, subject, body }:
{ person: Person, subject: string, body: string }) {
}
또는 type
이나 interface
를 사용할 수 있다.
interface EmailParams {
person: Person;
subject: string;
body: string;
}
function email({ person, subject, body }: EmailParams) {
}
class
는 값 공간과 타입 공간을 동시에 가진다.class Developer {
name: string;
domain: string;
constructor(name: string, domain: string) {
this.name = name;
this.domain = domain;
}
}
const me: Developer = new Developer('jihun', 'front-end');
위 코드에서 me:
뒤에 사용된 Developer
는 타입으로, new
키워드 뒤에 사용된 Developer
는 클래스의 생성자 함수인 값으로 동작한다.
enum
은 값 공간과 타입 공간을 동시에 가진다.열거형 키워드 enum
은 자바스크립트에서는 지원하지 않는 타입스크립트의 문법이다. enum
도 클래스처럼 타입 공간에서 타입을 제한하는 역할을 한다.
enum Status {
Ready,
Waiting,
}
enum Color {
Red,
Blue,
Green,
}
let status = Status.Ready;
status = Color.Green; // 실패
아래 예시에서는 enum
이 타입으로 사용되어, printDay()
함수의 key
인자에 넘겨줄 수 있는 값의 타입을 제한한다.
enum WeekDays {
MON = 'Mon',
TUES = 'Tues',
WEDNES = 'Wednes',
THURS = 'Thurs',
FRI = 'Fri',
}
type WeekDayKeys = keyof typeof WeekDays;
function printDay(key: WeekDayKeys, message: string) {
const day = WeekDays[key];
if (day <= WeekDays.WEDNES) {
console.log(`It's still ${day}day, ${message}`);
}
}
printDay('TUES', 'wanna go home');
✏️ 타입스크립트의
keyof
연산자는 해당 객체의 속성 키를 나타내는 유니온 타입을 생성한다.
위 코드에서keyof typeof WeekDays
를 통해 실제로 반환되는 값은"MON" | "TUES" | "WEDNES" | "THURS" | "FRI"
이다.
아래 예시와 같이 enum
도 class
처럼 값 공간에서 사용될 수 있다.
enum MyColors {
BLUE = '#0000FF',
YELLOW = '#FFFF00',
MINT = '#2AC1BC',
}
function whatMintColor(palette: { MINT: string }) {
return palette.MINT;
}
console.log(whatMintColor(MyColors));
타입스크립트에서 typeof
연산자는 값에서 쓰일 때와 타입에서 쓰일 때의 역할이 다르다. typeof
연산자가 값에서 사용되면 자바스크립트 런타임의 typeof
연산자로 작동하며, 타입에 사용되는 경우 타입스크립트 타입을 반환한다.
interface Person {
first: string;
last: string;
}
const person: Person = { first: 'jihun', last: 'kim' };
function email(options: { person: Person; subject: string; body: string }) {}
const v1 = typeof person; // 값은 'object'
const v2 = typeof email; // 값은 'function'
type T1 = typeof person; // 타입은 Person
type T2 = typeof email;
// 타입은 (options: { person: Person; subject: string; body: string }) => void
typeof
연산자를 클래스에 적용할 때는 주의해야 한다. 아래 예시를 통해 살펴보자.
class Developer {
name: string;
sleepingTime: number;
constructor(name: string, sleepingTime: number) {
this.name = name;
this.sleepingTime = sleepingTime;
}
}
const d = typeof Developer; // 값은 'function'
type T = typeof Developer; // 타입은 typeof Developer
const me: Developer = new Developer('jihun', 7);
type MeType = typeof me; // 타입은 Developer
const d = typeof Developer;
: 자바스크립트에서 클래스는 함수로서 취급되며, 클래스의 생성자 함수를 가리킨다. 따라서 d
에 할당된 값은 function
이다.type T = typeof Developer;
: T
는 Developer
클래스 자체의 타입이다. 즉, T
는 클래스의 생성자 함수를 포함하는 타입으로, 이 타입을 사용하여 Developer
클래스의 새 인스턴스를 아래와 같이 생성할 수 있다. const newInstance: InstanceType<T> = new Developer('홍길동', 10);
✏️
InstanceType<T>
는 타입스크립트에서 제공하는 유틸리티 타입 중 하나로, 생성자 함수 타입T
의 인스턴스 타입을 생성한다.
즉,T
가 클래스의 타입일 때,InstanceType<T>
를 사용하면 해당 클래스의 인스턴스 타입을 얻을 수 있다.
type MeType = typeof me;
: MeType
은 me
인스턴스의 타입, 즉 Developer
클래스의 인스턴스 타입이다. 여기서 typeof me
는 Developer
를 반환하는 것이 아니라, me
변수가 가리키는 객체의 타입, 즉 Developer
인스턴스의 타입을 의미한다.타입 단언(Type Assertion)은 개발자가 타입스크립트 컴파일러보다 더 정확한 정보를 가지고 있을 때 사용한다. 즉, 개발자가 특정 변수의 타입을 명시적으로 지정해 컴파일러에게 알려주는 방식이다. 타입 단언은 컴파일 단계에서만 사용되며, 런타임에는 영향을 미치지 않는다. 타입 단언에는 두 가지 문법이 있다.
as
를 사용한 방법let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
angle-bracket(<>)
을 사용한 방법let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;