다형성 즉 다른 구조를 가진다고 보면된다.
type SuperPrint = {
(arr: number[]):void
(arr: boolean[]):void
}
const superPrint:SuperPrint = (arr)=>{
arr.forEach(i => console.log(i))
}
superPrint([1,2,3,4])
superPrint([true,false,true])
superPrint(["hi","a","b"]);
call signatures에서 number,boolean 배열은 있지만, string배열은 없어서, 마지막 함수는 에러가 난다.
이를 해결하기 위해 call signatures(이하 콜)에 string 배열을 추가해줄 수도 있지만 더 좋은 방법이 있다.
타입의 placeholder같은 것이다.
concrete type을 사용하는 것 대신 쓸 수 있다.
콜을 작성할 때, 여기에 들어올 확실한 타입을 모른다면 generic을 사용해보자.
일단 콜에게 제네릭타입을 쓴다고 알려준다.
type SuperPrint = {
<T>(arr: T[]):void
}
타입스크립트는 자신이 발견한 타입으로 추론해서 바꿔준다.
모두 가능한것을 확인할 수 있다.
type SuperPrint = {
<T>(arr: T[]):T
}
const superPrint:SuperPrint = (arr)=>{
return arr[0];
}
type SuperPrint = {
<T,M>(arr: T[],b:M):T
}
const superPrint:SuperPrint = (arr)=>{
return arr[0];
}
superPrint([1,2,3,4],1)
superPrint([true,false,true],"hi")
또다른 제네릭 타입을 추가 하고 싶다면, 저렇게 해주면 된다!!
function superPrint<T>(a: T[]){
return a[0]
}
콜 없이 바로 함수로도 적용하는게 더 간단해 보이는듯..
자바 제네릭 할 땐,, 뭔가 어려워보여서 제대로 공부를 안했었는데
생각보다 쉽고 간편해서 좋다. 둥둥둥~🥁
interface SStorage<T>{
[key:string]:T
}
class LocalStorage<T>{
private storage:SStorage<T>={}
set(key:string,value:T){
this.storage[key] = value;
}
remove(key:string){
delete this.storage[key];
}
get(key:string):T{
return this.storage[key];
}
clear(){
this.storage = {}
}
}
const stringStorage = new LocalStorage<string>()
stringStorage.get("key");
stringStorage.set("hello","say hi~")
const booleanStorage = new LocalStorage<boolean>();
booleanStorage.get("xxx");
booleanStorage.set("hello",true);
LocalStorage클래스와, SStorage타입을 제네릭으로 받아준다.
string이든 boolean이든 타입을 지정해주어서, 해당 객체일 땐 특정 타입으로만 추론되게 할 수 있다.