| 제네릭
제네릭이란
제네릭은 데이터 형식에 의존하지 않으면서, 다른 데이터 타입들로 사용할 수 있는 방법이다
interface IGene{
data: string | number | object;
}
function gen(params: IGene){
console.log(typeof params.data);
}
gen({data:"아무거나"});
gen({data:25});
gen({data:{}});
제네릭이 없으면 위와같이 필요한 타입을 다 작성해야할것이다
이제 제네릭을 사용해보겟다
interface IGene<T>{
data:T
}
function gen(params: IGene<string>){
data: console.log(typeof params.data)
}
gen({data:"hi"})
위와같이 타입정보를 전달받는것과 같다
제네릭 예제
예시를 보자
interface IGene<T>{
data:T[]
}
function gen(params: IGene<string>){
data: console.log(typeof params.data)
}
gen({data:["hi","myname","is"]})
배열의 타입을 지정해줄수도있고
아래와 같은 방식으로 여러개도 가능하다
interface IGene<T,U>{
data:Array<T>,
name:U;
}
function gen(params: IGene<number,string>){
data: console.log(typeof params.data)
}
gen({name:"jae",data:[1,2,3]})
extends
제네릭에서는 extends 키워드를 사용할수있다
사용목적 : 1 제한,안정성 2 보장
1.제한 안정성
function add<T>(params: T){
if(typeof params === "string") console.log("문자열입니다");
else if (typeof params === "number") console.log("숫자입니다")
}
add<string>("hihihi");
add<number>(123);
위와 같이 만약 개발자가 string과 number만 사용하기로 의도 했는데
아래와 같이 의도와는 다르게 사용되어진다면 안된다
function add<T>(params: T){
if(typeof params === "string") console.log("문자열입니다");
else if (typeof params === "number") console.log("숫자입니다")
}
add<object>({});
add<boolean>(true);
이런 상황을 막기위해 아래와 같이 extends 를 사용해서 제네릭으로 들어올수있는 타입을 제한할수있다
구분은 | 로 한다
function add<T extends string | number>(params: T){
if(typeof params === "string") console.log("문자열입니다");
else if (typeof params === "number") console.log("숫자입니다")
}
add<string>("hi");
add<number>(12);
아래와같이 여러개도 가능
function add<T extends string | number, U>(params: T,params2: U){
if(typeof params === "string") console.log("문자열입니다");
else if (typeof params === "number") console.log("숫자입니다")
if(typeof params2 === "boolean") console.log("불린입니다");
else if( typeof params2 === "object") console.log("객체입니다");
}
add<string, boolean>("hi",true);
console.log('')
add<number,object>(12,{});
2.보장
function execute<T extends object>(params: T){
params.hi();
}
execute({
hi() {
console.log("hi!");
}
})
위 코드를 보면 메소드 실행을 맞게 적은것 같으나 실행시 아래와 같이 에러가 난다
params에는 어떤 객체가 들어올지 몰라서
params에 hi라는 메소드가 보장이 되지 않았기때문에 에러가 나는것이다
그래서 아래와 같이 보장 할 수 있다.
interface IHi {
hi: (name: string)=> void;
}
function execute<T extends IHi>(params: T){
params.hi("jae");
}
execute({
hi(name: string) {
console.log("hi!",name);
}
})
제네릭활용
//1
interface IData<T extends string | number> {
data: T;
}
//2
function returnParams<T>(params: T): T{
return params;
}
returnParams<string>("hi");
returnParams<number>(25);
returnParams<boolean>(true);
//3
function returnParams<T>(params: T): T{
return params;
}
const rp: <T>(params: T) => T = returnParams
interface IExecute {
rp: <T>(params: T) => T;
}
//4
interface IOb1{
name: string;
age: number;
}
interface IOb2{
city: string;
phone: number;
}
function prtKey<T extends object, U extends keyof T>(params: T, key: U): T[U] {
console.log(params[key]);
return params[key];
}
prtKey<IOb1, keyof IOb1>({name: "jae", age: 25},"name");
prtKey<IOb2, keyof IOb2>({city: "city", phone: 01011111111},"phone");
//5
class ClassName<T> {
constructor(private _data: T) {}
set data(newData: T) {
this._data = newData;
}
get data(): T{
return this._data;
}
}
반응형
'웹 개발 > #️⃣ TypeScript' 카테고리의 다른 글
TS | Import 와 Export (0) | 2023.06.12 |
---|---|
TS | 데코레이터 (0) | 2023.06.05 |
TS | key와 같이 쓰는 타입 (0) | 2023.06.03 |
TS | 대수타입 -union, intersection (0) | 2023.06.01 |
TS | 클래스 - readonly와 생성자 (0) | 2023.06.01 |