아래와 같은 예시가 있다고 할 때
function merge<U, V>(obj1: U, obj2: V) {
return {
...obj1,
...obj2
};
}
merge()
는 2개의 객체를 합쳐주는 제네릭 함수임.
let person = merge(
{ name: 'John' },
{ age: 25 }
);
console.log(result);
// Output:
{ name: 'John', age: 25 }
merge()
함수는 2개의 객체가 들어오기를 기대하고 있는데 아래처럼 객체가 아닌게 넘어오는거를 막지는 못함.
let person = merge(
{ name: 'John' },
25
);
console.log(person);
// Output:
{ name: 'John' }
위 코드는 에러가 안나오기는 함.
이렇게 모든 타입에 대해서 동작하는것보다 merge()
함수가 객체만 받도록 하려면 아래처럼 extends
키워드를 사용하면 됨.
function merge<U extends object, V extends object>(obj1: U, obj2: V) {
return {
...obj1,
...obj2
};
}
이제 위 merge()
에서는 에러가 나옴.
let person = merge(
{ name: 'John' },
25
);
// Error
Argument of type '25' is not assignable to parameter of type 'object'.
타입스크립트는 다른 타입 parameter에 의해 constrained 된 타입 parameter를 선언할 수 있음.
아래 함수는 prop()
함수가 객체와 property 이름을 받아서 이름을 받은 객체의 property 값을 리턴하고자 함.
function prop<T, K>(obj: T, key: K) {
return obj[key];
}
하지만 위 코드는 컴파일러에서 아래와 같은 에러가 나옴
Type 'K' cannot be used to index type 'T'.
이를 해결하려면 K
에 T
에 키임을 보장하는 constraint를 아래처럼 추가해주면됨.
이제 prop()
에 obj
에 존재하는 property 이름을 넘겨주면 컴파일러에러가 안생김.
function prop<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let str = prop({ name: 'John' }, 'name');
console.log(str);
// Output
John
반면에 객체에 존재하지 않는 키를 넘길 경우에 컴파일러가 에러 띄움.
let str = prop({ name: 'John' }, 'age');
// Error:
Argument of type '"age"' is not assignable to parameter of type '"name"'.
extends
키워드로 type parameter를 특정 타입으로 제한할 수 있음extends keyof
로 타입을 다른 오브젝트의 property로 제한할 수 있음