type
은 특정 타입에 별칭을 붙이는 용도로 사용합니다. 이를 사용하여 객체를 위한 타입을 설정할 수도 있고, 배열, 또는 그 어떤 타입이던 별칭을 지어줄 수 있습니다.
type Person = {
name: string;
age?: number; // 물음표가 들어갔다는 것은, 설정을 해도 되고 안해도 되는 값이라는 것을 의미합니다.
};
// & 는 Intersection 으로서 두개 이상의 타입들을 합쳐줍니다.
type Developer = Person & {
skills: string[];
};
const person: Person = {
name: '김사람'
};
const expert: Developer = {
name: '김개발',
skills: ['javascript', 'react']
};
type People = Person[]; // Person[] 를 이제 앞으로 People 이라는 타입으로 사용 할 수 있습니다.
const people: People = [person, expert];
type Color = 'red' | 'orange' | 'yellow';
const color: Color = 'red';
const colors: Color[] = ['red', 'orange'];
- Interface types have many similarities to type aliases for object type literals, but since interface types offer more capabilities they are generally preferred to type aliases.
- (객체 타입에 대해서 Interface와 type aliases는 많은 비슷한점이 많다. 그러나 interface가 더 많은 사용법을 제공한 이래로, 일반적으로 type aliases보다 더 선호되어지고 있다.)
덧붙이기
type aliases와 interface는 어떤 용도로 사용을 해야 할까?
클래스와 관련된 타입의 경우엔 interface 를 사용하는게 좋고,
일반 객체의 타입의 경우엔 그냥 type을 사용해도 무방합니다.
사실 객체를 위한 타입을 정의할때 무엇이든 써도 상관 없는데 일관성 있게만 쓰시면 됩니다.
제너릭(Generics)은 타입스크립트에서 함수, 클래스, interface, type alias 를 사용하게 될 때 여러 종류의 타입에 대하여 호환을 맞춰야 하는 상황에서 사용하는 문법입니다.
예를 들어서 우리가 객체 A 와 객체 B 를 합쳐주는 merge 라는 함수를 만든다고 가정해봅시다. 그런 상황에서는 A 와 B 가 어떤 타입이 올 지 모르기 떄문에 이런 상황에서는 any 라는 타입을 쓸 수도 있습니다.
그런데, any를 사용하게되면 하면 타입스크립트를 사용안하는거나 다름이 없습니다. 결과가 any 라는 것은 즉 merged 안에 무엇이 있는지 알 수 없다는 것 입니다.
나쁜 예)
function merge(a: any, b: any): any {
return {
...a,
...b
};
}
const merged = merge({ foo: 1 }, { bar: 1 });
Generics를 함수에 사용한 좋은 예1)
function merge<A, B>(a: A, b: B): A & B {
return {
...a,
...b
};
}
const merged = merge({ foo: 1 }, { bar: 1 });
Generics를 함수에 사용한 좋은 예2)
function wrap<T>(param: T) {
return {
param
}
}
const wrapped = wrap(10);
Generics를 interface에서 사용한 좋은 예)
interface Items<T> {
list: T[];
}
const items: Items<string> = {
list: ['a', 'b', 'c']
};
Generics를 type에서 사용한 좋은 예)
type Items<T> = {
list: T[];
};
const items: Items<string> = {
list: ['a', 'b', 'c']
};