제너릭 타입

핵심 포인트

  • 상수 타입 매개변수 const T - TS v5.0에 추가됨

    • 타입을 좁힐 때 사용 (ex: string을 유니온 리터럴로 추론되게 할 때)

  • 타입 매개변수와 제약(extends)을 동일하게 생각하지 마라.

    • 타입 매개변수는 제약에 대입할 수 있는 모든 타입을 의미

    • 타입 매개변수는 제약보다 더 넓은 타입, (제약이 더 좁은 타입이라 생각)

  • 강박적으로 제너릭을 쓸 필요는 없다. 특히, 원시값 타입만 사용한다면 대부분 제약을 걸지 않아도 된다.

제너릭

타입간에 중복을 제거하기 위해 제너릭을 사용

interface Person<N, A> {
  type: 'human',
  race: 'yellow',
  name: N,
  age: A,
}

interface Zero extends Person<'zero', 28> {}
interface Nero extends Person<'nero', 32> {}

// Array 타입도 제너릭
// 제너릭이 없었다면 스트링배열, 넘버배열을 따로 타입을 선언해줬어야 됬을것
interface Array<T> {
  [key: number]: T,
  length: number
  //...
}
  • 표기는 <> 로 하며 인터페이스 이름 바로 뒤에 위치

  • <> 안에 타입 매개변수를 넣어서 사용

  • 제너릭 타입으로 타입간 중복을 줄이고 재사용성을 높힘

제너릭 표기 위치

함수에서 함수 선언문이냐 표현식이냐에 따라 제너릭 표기 위치가 달라짐

함수는 제너릭표기가 인자 앞에 위치한다고 생각

  • interface 이름<타입 매개변수들> {...}

  • type 이름<타입 매개변수들> = {...}

  • class 이름<타입 매개변수들> {...}

  • function 이름<타입 매개변수들>(...) {...}

  • const 함수이름 = <타입 매개변수들>(...) ⇒ {...}

제너릭 기본값

타입 매개변수에 기본값을 사용할 수 있다.

타입 추론

타입스크립트는 제너릭에 직접 타입을 넣지 않아도 추론을 통해 타입을 알아 낼 수 있다.

  • 이처럼 타입스크립트가 추론을 통해 타입을 알아낼 수 있는 경우는 직접 <> 타입을 넣지 않아도 된다.

    • 실제로도 직접 넣지 않는 경우가 더많음

  • 타입스크립트 5.0 버전에서 상수 타입 매개변수 (const T)가 추가됨

상수 타입 매개변수

  • ❓T를 string 대신 'a' | 'b' | 'c' 같은 유니온으로 추론되게 하려면?

    • 타입 매개변수 앞에 const 수식어를 추가하면 타입 매개변수 T를 추론할 때 as const를 붙인 값으로 추론됨

제너릭에 제약 걸기

타입 매개변수에는 제약(constraint)를 사용 가능

extends 문법으로 타입 매개변수의 제약을 표시

  • 타입의 상속을 의미하던 extends 와는 사용법이 다르므로 구분!!

  • 제약이 걸리면 제약에 어긋나는 타입은 입력할 수 없지만 제약보다 더 구체적인 타입은 입력 가능

    • 이러한 점에서 제약은 기본값과는 다르다.

제너릭 제약을 사용할 때 흔히 하는 실수

  • ❌ 타입 매개변수와 제약을 동일하게 생각하는 것

  • 먼저 타입 매개변수가 제약에 대입할 수 있는 타입인지를 따져보아야 한다.

  • 강박적으로 제너릭을 쓸 필요는 없다. 특히, 원시값 타입만 사용한다면 대부분 제약을 걸지 않아도 된다.

  • T 는 정확히 VO가 아니라 VO에 대입할 수 있는 모든 타입을 의미

    • 따라서 { value: string, another: string }도 T가 될 수 있다.

    • 이러면 { value: string } 은 T가 아니다. 따라서 에러가 발생함.

  • 인자값의 타입은 열려있고, 반환값의 타입은 닫혀있다. (공변성, 반공변성 참고)

  • never 타입 때문, never는 모든 타입에 대입할 수 있으므로 never extends boolean은 참이다.

  • 따라서 T가 never 일 수 있으므로 false를 기본값으로 넣는 것이 불가능한 것

Last updated