제네릭 소개


제네릭은 타입을 함수의 파라미터처럼 사용하는 것을 의미한다. 제네릭은 재사용성이 높은 컴포넌트를 만들 때 자주 사용한다. 한 가지 타입보다 여러가지 타입에서 동작하는 컴포넌트를 생성할 때 유용하다.

제네릭 기본 문법


<aside> 💡 T는 Type parameter의 약자로 관용적으로 사용한다. 꼭 T를 사용해야하는건 아니다.

</aside>

아래 함수의 text파라미터엔 hi 10 true 등 어떤 타입의 값이 들어가더라도 그대로 반환한다. 이렇게 모든 타입을 받을 수 있는 이유는 타입을 따로 지정하지 않았기 때문에 암묵적으로 any 타입이 돼서 그런 것이다.

function getText(text) {
  return text;
}

 타입은 타입 검사를 하지 않기 때문에 어떤 타입이 들어가고, 반환되는지 알 수 없다.

any 타입은 타입 검사를 하지 않기 때문에 어떤 타입이 들어가고, 반환되는지 알 수 없다.

아래 함수는 제네릭 기본 문법이 적용된 형태다. 위 함수와 비슷하게 어떤 타입이든 파라미터로 넘길 수 있다.

function getText<T>(text: T): T {
  return text;
}

함수를 호출할 때 아래처럼 타입을 직접 넘겨줄 수 있다. 아래 2가지 방법으로 호출할 수 있다.

getText<string>('hi') // 혹은 getText('hi')
getText<number>(10) // 혹은 getText(10)
getText<boolean>(true) // 혹은 getText(true)

getText<string>('hi') 코드로 함수를 호출했을 때 제네릭이 적용된 함수는 아래 모양과 같아진다. 함수를 호출할 때 제네릭 값으로 string을 넘겼기 때문에 함수의 T 부분이 string으로 적용된 것이다(정확히 말하면 함수를 호출할 때 넘긴 타입에 대해 타입스크립트가 추정할 수 있게 된 것)

// 파라미터, 반환값 모두 string
function getText<string>(text: string): string {
  return text;
}

제네릭 타입 제한


만약 함수 인자로 받은 문자열의 length를 확인하고 싶다면 .length 메소드를 사용하면 된다. 하지만 아래처럼 ts(2339) 컴파일러 에러가 발생한다. 제네릭 함수 코드의 T 는 파라미터와 반환 값 타입에 any를 지정한 것과 같은 동작을 한다. 컴파일러 입장에선 .length 속성이 없는 number 타입 등이 올 수 있는 것을 감안하여 .length 속성을 허용하지 않는 것이다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0ec03729-8f14-4b41-91ce-40047a71080b/Untitled.png