다음 코드의 문제점은 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 함수를 실행할 수 없게 된다.
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 |
댓글