TS)제네릭! 타입을 파라미터로
오늘은 제네릭 타입에 대해 공부해 보겠습니다.
함수나 클래스를 만들때, 타입을 지정하지않고 실제로 함수를 호출할때나 클래스의 인스턴스를 만들때 타입을 매개로 전달하는 방법입니다.
기본 코드)
function foo<T>(x: T[]) :T {
return x[0];
}
let a = foo<number>([4,2])
let b = foo<string>(['kim', 'park'])
// 타입을 알아서 유추해주기 때문에, 아래와 같이 써도 에러가 발생하지 않습니다.
let a = foo([4,2]) // T는 number로 유추한다.
let b = foo(['kim', 'park']) // T는 string으로 유추한다.
T라는 임의의 타입을 지정해두고 함수를 호출할때 number, string 라는 타입을 지정해주고 있습니다.
예시 1)
function bar<T>(x:T){
return x-1
}
bar<number>(1) // 에러
위 코드는 에러가 발생합니다. 함수를 정의 할때, T는 어떤 타입이 될 지 정해지지 않았는데 x-1 연산을 수행하기 때문입니다.
이는 narrowing을 통해 해결할 수 있지만, T 자리에 들어오는 타입을 미리 number로 제한해두면 더 간단할 것 같습니다.
function bar<T extends number>(x:T){
return x-1
}
bar<number>(1)
extends는 인터페이스 에서 속성값을 '확장,복사' 할 때 사용하였습니다.
제네릭에서도 마찬가지인데, 내장되어있는 number 타입의 속성을 T타입에 그대로 복사하는 것입니다.
T는 number의 속성을 가지고 있으므로, x-1과 같은 연산을 해도 에러가 나지 않습니다.
제네릭 constraint 연습하기
function bar<T>(x:T){
return x.length;
}
bar<string>('몇글자일까요'); // 에러가 발생합니다.
코드의 목적은, string의 길이를 반환하는 것 입니다.
그러나 x가 어떤 타입이 될 지 정해지지 않으므로, x.length를 하면 에러가 발생하죠
number타입일수도 있으니까요.
x에 length라는 프로퍼티가 무조건 존재하도록 제한을 걸어두어야 할 것 같습니다.
type MyType = {
length:number
}
function bar<T extends MyType>(x:T){
return x.length;
}
bar<string>('몇글자일까요'); // 성공!
T 타입은 length라는 프로퍼티를 가진다 라고 보장을 해주니, 에러가 해결됐습니다!
Class에 제네릭 적용하기
class Person<T> {
name;
constructor(name:T){
this.name = name;
}
}
new Person<string>('이름');
new Person<string[]>(['aa','bb','cc'])
new Person<number>(1)
클래스도 마찬가지로 제네릭을 이용하면 확장성에서 큰 장점이 있습니다.
또 연습할만한 제네릭코드가 있다면 추가하겠습니다!
Author And Source
이 문제에 관하여(TS)제네릭! 타입을 파라미터로), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sae1013/TS제네릭-타입을-파라미터로저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)