[TypeScript] Generic

이어진·2025년 1월 22일

타입스크립트

목록 보기
3/5
post-thumbnail

사용 이유

function 함수(x : unknown[]) {
  return x[0]
}
let a = 함수([4, 2])
console.log(a + 1) // ❌

이런 코드에서 ❌ 친 부분은 분명 에러가 날 겁니다. 왤까요?

인간이 보기에 a는 분명히 숫자입니다. 하지만 타입은 unknown입니다.

타입스크립트는 타입을 알아서 변경해주지 않습니다. 따라서 사람이 타입을 직접 정해주지 않는 이상 알아서 return 타입이 문자열이야~ 숫자야~ 해주지 않는다는 겁니다.

그래서 제네릭을 써봅시다

파라미터로 타입을 입력하는 함수
function 함수<Type>(x : Type){
  return x - 1
}

제네릭 함수를 사용하면 확장성이 좀 있습니다.

let a = 함수<number>(), let b= 함수<string>() 등 내가 원하는 타입을 넘길 수 있습니다.

이건 왜 에러가 나는데여

function 함수<Type>(x : Type) {
  return x - 1 // 이부분 에러
}
let a = 함수<number>(100)

이렇게 했을 때 오류가 납니다.

어 왜 나 number 타입도 잘 전달해주고 파라미터도 100으로 숫자 넣어줬는데?

만약 let a = 함수<number>(100) 부분이 없다고 생각해보십쇼. 그냥 function 함수 자체로 타입이 불확실합니다. 타입에 number 말고 다른 게 들어올 수도 있지 않습니까? 때문에 에러가 납니다.

그럼 어떻게 해야하냐 당연히 Narrowing 해야합니다.

또는 타입파라미터를 제한하는 방식도 가능합니다.

Generic 타입 제한하기 (constraints)

  • 타입 파라미터를 제한 두는 방법
function 함수<Type extends number>(x: Type) {
  return x - 1
}

이렇게 extends 사용해서 Type이 우측에 있는 속성을 가지고 있는지를 확인해준다.
interface 문법에 쓰는 extends와는 살짝 다른 느낌입니다. 그 extends는 복사인데, 이 extends는 오른쪽과 비슷한 속성을 가지고 있는지 확인하는 if문 느낌입니다.

  • 커스텀 타입으로도 제한을 둘 수 있다.
interface LengthCheck {
  length : number
}
function 함수<Type extends LengthCheck>(x: Type) {
  return x.length
}
let a = 함수<string>('100')
  1. length 속성을 가지고 있는 타입을 하나 만들었습니다.
  2. 그걸 extends 해주면 Type도 length 속성을 복사해서 가집니다.
  3. 그래서 Type은 length가 분명히 있기 때문에 Type을 부여받은 x.length 조작이 가능합니다.

⚠️ <number> 시에는 오류가 납니다. number 같은 경우에는 number.length가 불가능하기 때문이죠. string이나 string[] 같은 경우는 에러 없이 잘 동작합니다.

(참고)
class도 <>로 타입파라미터를 집어넣을 수 있습니다. type Age<Type> = Type 이런 식으로도 타입 변수에 사용 가능합니다.

profile
코딩하는 말하는 감자

0개의 댓글