3.2 Polymorphism
// type SuperPrint = {
// (arr: number[]):void
// (arr: boolean[]):void
// (arr: string[]):void
// (arr: (number |boolean)[]):void
// }
// concrete type: number,boolean,string,void,
// generic은 플래이스 홀더
// 1. typestript에 generic사용한다고 말하라 함수 앞에.<Potato>.
// type SuperPrint = {
// <T>(arr:number[]):void // 이 콜 시그니처가 제네릭을 받는다.
// }
// type SuperPrint = {
// <T>(arr:T[]):void // 그리고 다음을 바꿔.
// }
const superPrint: SuperPrint = (arr) => arr[0]
type SuperPrint = {
<T>(arr:T[]):T // 리턴을 해야 한다면 이렇게 바꿔. 그 타입 중 하나를 리턴한다는 것.
}
const a = superPrint([1,2,3,4])
const b = superPrint([false,true,true,false])
const c = superPrint([1,2,3,4])
const d = superPrint([1,2,true,false])
//generic으로 call signature를 바꾼다.
3.3 Generic Recap
// type SuperPrint = {
// <Type>(arr:Type[]):Type
// }
// const superPrint: SuperPrint = (a) => a[0] //괄호가 없으면 바로 리턴한다.
// const a = superPrint([1,2,3,4])
// const b = superPrint([false,true,true,false])
// const c = superPrint([1,2,3,4])
// const d = superPrint([1,2,true,false])
//generic으로 call signature를 바꾼다.
// 그럼 any쓰면 되지않냐?
//d.toUpper
// a.toUpperCase()도 에러가 안나서 보호 못받음.
//타입을 하나 더 추가하고 싶다면?
type SuperPrint = {
<T,M>(a:T[], b:M):T
}
const superPrint: SuperPrint = (a) => a[0] //괄호가 없으면 바로 리턴한다.
const a = superPrint([1,2,3,4],"x")
const b = superPrint([false,true,true,false],"x")
const c = superPrint([1,2,3,4],"x")
const d = superPrint([1,2,true,false],"x")
console.log(d)
// 타입스크립트는 제네릭이 처음 사용되는 지점을 기반으로 이 타입이 무엇인지 알게 됨
// 순서가 중요하다.
3.4 Conclusions
// type SuperPrint = {
// <T>(a:T[]):T
// }
// const superPrint: SuperPrint = (a) => a[0] //괄호가 없으면 바로 리턴한다.
// const a = superPrint([1,2,3,4])
// const b = superPrint([false,true,true,false])
// const c = superPrint([1,2,3,4])
// const d = superPrint([1,2,true,false])
// // 타입스크립트는 제네릭이 처음 사용되는 지점을 기반으로 이 타입이 무엇인지 알게 됨
// // 순서가 중요하다.
// // 근데 제네릭 만들 일은 거의 없을 꺼다.
// //사용만 하겠지.
type Player<E> = {
name:string
extraInfo:E
}
type NicoExtra = {
favFood:string
}
type NicoPlayer = Player<NicoExtra>
const nico: Player<NicoExtra> = {
name:"nico",
extraInfo:{
favFood:"kimchi"
}
}
const lynn:Player<null> = {
name:"lynn",
extraInfo:null
}
과제
- 현재까지 배운 것을 토대로, 두 함수에 대한 구현과 함께 호출 시그니처(call signatures) 를 작성해주세요
- last(arr): 이 함수는 배열의 마지막 요소를 반환해야 합니다.
- prepend(arr, item): 이 함수는 배열의 시작 부분에 item을 넣고 return해야 합니다.
type SuperPrint = {
<Type>(arr:Type[]):Type
}
const last: SuperPrint = (a) => a[a.length-1]
console.log(last([1,false,"last"]))
type Prepend = {
<T,M>(a:T[],b:M):(T|M)[]
}
const prepend: Prepend = (arr,item)=> [item, ...arr]
const arr = prepend([1,2,3],"Good Morning!")
console.log(arr)