타입스크립트 TS 공부 #5 generic

사공 오·2022년 5월 5일
0

TS 기초 공부

목록 보기
5/7
post-thumbnail

Generic

함수에서 파라미터를 정의하듯이 타입을 파라미터화 할 수 있다.
한가지가 아니라 다양한 타입을 쓸 수 있도록 정의


함수에서 제네릭 사용하기

// function createPromise(x: number, timeoute: number){ //x: number 대신
function reatePromise<T>(x: T, timeoute: number){ //타입을 파라미터화하기 <T>-타입변수
    // return new Promise((resolve: (v: T) => void, reject) => {
    return new Promise<T>((resolve, reject) => { // 타입을 제네릭으로 정의해서, 타입전달이 가능해서 이렇게 표현할 수 있음 
        setTimeout( () => {
            resolve(x);
        }, timeoute); 
    });
}
// 전달받은 timeoute시간 뒤에 x가 resolve됨

createPromise("eh", 100) //1라는 숫자를 넣으면 T의 타입이 숫자로 정의되고

createPromise<string>("1", 100) //<string> 으로 타입변수를 문자열로 정의해주면 문자열로 정의됨

createPromise("1", 100) //<string> 으로 타입변수를 문자열로 정의해주면 문자열로 정의됨 (위에 new Promise<T>((resolve, reject) 이렇게 정의하면)
createPromise("eh", 100) //"eh"라는 문자열을 넣으면 T의 타입이 문자열로 정의되고
    .then(v => console.log( ));  //이렇게 v.치면 문자열에서 접근할 수 있는 매서드들이 나와서 선택가능

타입을 파라미터화하기 -타입변수

function createTuple2<T, U>(v: T, v2: U): [T, U] {
    return [v, v2]
}
const t1 = createTuple2("user1",1000);

t1[0].charAt //문자열
t1[1].toExponential // 숫자 타입 유지됨

function createTuple3<T, U, D>(v: T, v2: U, v3: D): [T, U, D] { //<T, U, D>처럼 타입파라미터 이름도 쓸수 있다 타입은 대문자로 쓰는게 관례
    return [v, v2, v3]
} //3개짜리 튜플 만들기도 가능 

매개변수가 여러개일 경우에도 사용가능
-> 타입을 유지하면서 코드를 작성할 수 있게한다.

class 에서 제네릭 사용하기

class LocalDB <T>{ 
    constructor(private localStroageKey: string){ //생성자로 localStroageKey이거를 받고
    }
    add(v: T){ //집어넣거나
        this.localStroageKey.setItem(this.localStroageKey, JSON.stringify(v)); //json으로 문자를 만들어서 집어넣고
    }
    get(): T { // 가저오거나 한다
        const v = this.localStroageKey.getItem(this.localStroageKey); 
        return (v) ? JSON.parse(v) : null; //문자열을 parse로 파싱을 해서 자바스크립트에서 사용하는 데이터로 변환해서 리턴
    }
}

interface User { name: string}

const userDb = new LocalDB<User>('user');
userDb.add({name: 'ony'});
// userDb.add('hello');  - 타입이 유저와 맞지않아서 오류남 오류남 
const userA = userDb.get();
userA.name;

> #### interface에서 제네릭 사용하기 ```ts interface DB { add(v: T): void; get(): T; }

class D implements DB { //D 이렇게 클래스에도 타입변수 정의해야 안에서 사용 가능
add(v: T): void {
throw new Error("Method not implemented.");
}
get(): T {
throw new Error("Method not implemented.");
}

}

interface JSONSerialier {
serialize() : string;
} //제이슨을 시리얼라이즈해서

class LocalDB2 implements DB{ //T를 특정한 타입JSONSerialier 의 하위타입으로 범위를 고정시켜서
constructor(private localStroageKey: string){
}
add(v: T){ //전달받은 값에서
this.localStroageKey.setItem(this.localStroageKey, v.serialize()); //전달받은 값 내에서 시리얼라이즈해서 사용
}
get(): T { // 가저오거나 한다
const v = this.localStroageKey.getItem(this.localStroageKey);
return (v) ? JSON.parse(v) : null;
}
}

  
<br>
  
> #### 조건부 타입에서 제네릭 사용하기
  
```ts
  interface Vegitable {
    v: string;
}

interface Meat {
    m: string;
}

interface Cart2<T > {
    getItem(): T  extends Vegitable ? Vegitable : Meat; // 삼항연산자로 조건부타입을 활용하기
}

// const cart1: Cart2<string> = { //string을 받으면 Meat으로고정됨
const cart1: Cart2<Vegitable> = { // Vegitable받으면 Vegitable으로 실행되어서
    getItem(){
        return {
            // m: ''
            v: '' //Vegitable일때 리턴되어야할 거 제시
        }
    }
}

cart1.getItem();
  

**- 제네릭을 사용하면 function, class, interface에서 하나의 타입뿐만 아니라 여러타입을 처리할 수 있다.** **- 여러타입에 대해 이 하나의 기능이 동작하게하고 이타입이 유지가 되어서 타입세잎한 코드를 작성할 수 있게 도와준다.**

0개의 댓글