
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 해야합니다.
또는 타입파라미터를 제한하는 방식도 가능합니다.
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')
length 속성을 가지고 있는 타입을 하나 만들었습니다.extends 해주면 Type도 length 속성을 복사해서 가집니다.x는 .length 조작이 가능합니다.⚠️ <number> 시에는 오류가 납니다. number 같은 경우에는 number.length가 불가능하기 때문이죠. string이나 string[] 같은 경우는 에러 없이 잘 동작합니다.
(참고)
class도 <>로 타입파라미터를 집어넣을 수 있습니다. type Age<Type> = Type 이런 식으로도 타입 변수에 사용 가능합니다.