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;
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();