본문 바로가기
  • 살짝 구운 김 유나
Web/TypeScript

[TypeScript] 제네릭 (Generics)

by yunae 2023. 3. 1.

다음 코드의 문제점은 number 타입에 대한 유효성 검사만 가능하다는 것이다.

function checkNotNullBad(arg: number | null): number {
    if (arg == null) {
      throw new Error("not Valid Number!");
    }
    return arg;
  }

any 타입을 사용하는 것도 좋지 않은 방법임 => 타입이 보장되지 않기 때문

function checkNotNull(arg:any | null): any {
    if (arg == null) {
        throw new Error('not valid number!')
    }
    return arg;
  }

  const result = checkNotNull(123);

 

 

 

이때, Generic을 사용할 수 있다.

아래의 함수에 어떤 인자를 전달하더라도 null이 아닌 경우에 인자 타입 그대로 return함

=> 유연하지만 type을 보장받을 수 있음

=> 어떤 임의의 타입으로 결정된다.

=>  주로 대문자 한글자로 작성한다.

function checkNotNull<T>(arg: T | null): T {
    if (arg == null) {
      throw new Error("not valid number!");
    }
    return arg;
  }

 

 

 

[예시 코드]

// either : a or b
interface Either<L, R> {
  left: () => L;
  right: () => R;
}

class SimpleEither<L, R> implements Either<L, R> {
  constructor(private leftValue: L, private rightValue: R) {}
  left(): L {
    return this.leftValue;
  }

  right(): R {
    return this.rightValue;
  }
}

const either = new SimpleEither(4, 5);
either.left(); // 4
either.right(); // 5

const best = new SimpleEither({ name: "yuna" }, "hello");
best.left(); // {name:'yuna'}
best.right(); // 'hello'

 

 

 

 

제네릭에 조건을 줄 수 있는 방법

[예시 코드]

interface Employee {
  pay(): void;
}

class FullTimeEmployee implements Employee {
  pay() {
    console.log("full time!");
  }
  workFullTime() {}
}

class PartTimeEmployee implements Employee {
  pay() {
    console.log("part time!");
  }
  workPartTime() {}
}

function pay(employee: Employee): Employee {
  employee.pay();
  return employee;
}

const yuna = new FullTimeEmployee();
const bob = new PartTimeEmployee();
yuna.workFullTime();
bob.workPartTime();

const yunaAfterPay = pay(yuna);
const bobAfterPay = pay(bob);

다음 함수를 실행했을 때,

FullTime, PartTime 직원이라는 정보를 잃어버리고 Employee 타입으로 변경됨

// 세부적인 타입을 인자로 받아서 추상적인 타입으로 다시 리턴하는 함수는 좋지 않음
function pay(employee:Employee): Employee {
  employee.pay()
  return employee
}

const yunaAfterPay = pay(yuna)
const bobAfterPay = pay(bob)

따라서 workFullTime, workPartTime 함수를 실행할 수 없게 된다.

pay 함수에만 접근 가능함

Employee를 확장한 타입일 경우에만 적용하기

function pay<T extends Employee>(employee: T): T {
  employee.pay();
  return employee
}

 

 

 

[추가 내용]

const obj = {
  name: "yuna",
  age: 20,
};

const obj2 = {
  animal: "🐛",
};

function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

console.log(getValue(obj, "name")); // yuna
console.log(getValue(obj, "age")); // 20
console.log(getValue(obj2, "animal")); //🐛

T 타입의 객체 키 중 하나의 값 K

<K extends keyof T>

 

 

 

상여자달팽이특. 남 신경 안씀.

'Web > TypeScript' 카테고리의 다른 글

[TypeScript] 타입스크립트 컴파일러  (0) 2023.03.07
[TypeScript] Utility Type  (0) 2023.03.05
[TypeScript] Composition  (0) 2023.02.25
[TypeScript] 객체지향 (OOP)  (0) 2023.02.24
[TypeScript] 기본 타입 #2  (0) 2023.02.22

댓글