TypeScript - 5

doodream·2021년 6월 17일
0

TypeScript

목록 보기
5/6
post-thumbnail

Generic

Generic은 unknown 타입과 같이 미리 정해지지 않은 타입이면서 한번 정해지면 해당하는 타입처럼 행동합니다.

function insertAtBeginning(arr: any[], value: any) {
  return [value, ...arr];
}

const demoArr = [1, 2, 3];
const updateArr = insertAtBeginning(demoArr, -1);

console.log(updateArr[0].split("")); //error

위 코드에서는 error가 나는데 insertAtBeginning 함수에서 인수의 정의가 any이기 때문에 typeScript가 updateArr[0]이 문자열일수도 있어서 split을 호출하는 것에 대해 에러를 표시를 안합니다.
이점은 함수의 데이터 타입 정의를 number이나 그렇게 하면 되는것 아닌가 하지만 애초에 insertAtBeginning 함수의 설계 자체가 number, string 모두 유념해서 만들어졌기 때문에 그렇게 하면 적절하지 않습니다.
이때 generic이 필요하다.

여기서의 쟁점은 인수로 받은 arr의 원소의 타입과 value의 원소타입이 같아야 한다라는 것 만 지키면 함수의 설계상 이상이 없습니다.

그렇다면 그것을 정의하려면 어떻게 해야할까요?

function insertAtBeginning<T>(arr: T[], value: T) {
  return [value, ...arr];
}

const demoArr = [1, 2, 3];
const updateArr = insertAtBeginning(demoArr, -1);

console.log(updateArr[0].split("")); //error

이렇게 Generic을 사용합니다. 여기서 T라는 것은 일종의 관행으로서 어떤 이름이 들어가든 상관은 없습니다. T는 타입이 정해지지는 않았지만 string 이나 number등 primitive 타입이 들어가면 해당 타입으로 명시를 해줍니다.

사실 number[], string[] 같은 문법들은 모두 Generic 입니다.

function insertAtBeginning(arr: number[], value: number) {
  return [value, ...arr];
}
=== 
function insertAtBeginning(arr: Array <number>, value: number) {
  return [value, ...arr];
}

위 코드의 실상은 바로 아래 코드와 완벽히 같습니다.
number[] 같은 타입은 어쩔수 없이 Array 입니다. Array에서 해당원소가 number인것일 뿐입니다. 따라서 Array 이라는 제네릭을 통해서 원소값을 명시해줌으로서 arr을 정의해줍니다. 즉, number[] 같은 문법은 sugar Syntax 였던 것 입니다.

profile
일상을 기록하는 삶을 사는 개발자 ✒️ #front_end 💻

0개의 댓글