본문 바로가기

TYPESCRIPT

[타입스크립트] call signature / overloading / poly / generic

Call Signature

해당 함수 위에 마우스를 올리면, 함수를 어떤 것을 호출해야 하는지 알려줌 

함수의 타입과 함수의 인자의 타입, 반환 타입을 알려줌 

function plus (p:number, l: number){
// p와 l의 타입을 입력하는 것만으로도 타입을 확인 가능 > call signiture
	return a+b
    }
    
// 화살표 함수로 선언 
// p와 l도 number 이면 a+b로 실행 
// 작성하던 타입을 작성하지 않고, plus만의 타입을 만들고자 함 >  call signiture 
cosnt plus = (p:number, l: number)=> a+b

 ** React.js로 함수를 쓴다면, props로 함수를 보내게 되면 타입스크립트로 어떻게 함수가 작동하는지 설명이 필요함

type plus = (a:number, b:number) => number; // = call signature

const Plus : plus = (a,b) => a+b
// a,b의 파라미터가 number라는 것을 알고 있음 
// 타입을 생각할 수 있게 하고, 타입을 설명한 뒤에 코드를 구현하도록 하는 기능

 Overloading 

메소드 오버로딩(function overloading)은 직접 작성하기보다는,

외부 라이브러리에 자주 보이며, 하나의 함수가 복수의 call Signature 를 가질 때 발생함 

 

동일한 이름에 매개변수 타입 / 리턴 타입이 다른 여러 버전의 함수를 만드는 것 (function overloads) 

TypeScript에서는 오버로드 signature를 작성해 다양한 방식으로 호출할 수 있는 함수를 지정 가능 

 

활용예시) Next.js는 라우터를 가짐, 페이지를 바꾸고 싶다면, 패키지나 라이브러리는 두 가지 경우의 오버로딩으로 디자인

1) Router.push ({ path : "/home", state :1}) // object로 보내는 방법 

2) .push("/home") // string 으로 보내는 방법 

type student = {
	(a:number, b:string):nubmer 
    (a:number, b:number):number // :number ?
    }
    
    
// 만약 b타입이 string이라면 a를 return 
// 아니아면 a+b를 리턴 
const Student : student = (a,b) => {
	if(typeof b === "string") return a
    return a+b
    }

 1) 다른 call signature를 가지지만 하나의 argument(1개) 를 가지고 있음 (path :string_): void

// 패키지 or 라이브러리 디자인 시 사용하는 코드 

// 타입 작성
type Config ={
	path :string,
    state :object
    
}


type Push = {
	(path :string):void 
    	(obj: config) :void
    }
    
const push :Push = (config) => {
	// comfig를 string타입인지 체크하도록 하고 
    //맞다면 config를 출력하고 아니라면 path를 출력
	if(typeof config === "string"){ console.log(config)}
    else {
    	console.log(config.path, config.state)
        }
  }

 2)  한개의 argument에 여러개의 파라미터를 가지는 경우

type a = {
	(a:number, b:number) :number 
    (a:number, b:number, c:number ) :number 
    }
    // 매개변수의 데이터 타입/ 수가 다른 경우는 예외 처리 
    // 다른 개수의 파라미터를 가지는 경우(c) 파라미터에 추가 옵션을 지정해줘야 함 

const A :a = (a,b,c? : number) => {
	if(c) return a+b+c // c가 있다면 a+b+c를 리턴 
	return a+b
}

 

 

 Polymorphism, 다형성 

타입스크립트에서 함수는 string / object를 첫번째 파라미터로 가질 수 있다. > 다형성

// 배열을 받고 배열 요소를 하나씩 프린트

type SuperPrint = {
	// call signature > number 배열을 받고 void를 리턴 (아무것도 return x)
    // concrete type: string boolean number..
	(arr : number[]) : void
    (arr : boolean[]) : void
    (arr : string[]):void
    (arr : (number|boolean)[]):void //3을 동작하기 위해 추가
    }
    
    // arr배열을 받도록 아무것도 리턴하지 않음 
    // 첫번째 조건인 배열을 받아서, 배열의 요소를 콘솔로 출력
    const superprint : SuperPrint = (arr) => {
    	arr.forEach(i => console.log(i))
    }
    
    superPrint([1,2,3,4]) 
    superPrint([true, false, true])
    superPrint(["a", "b","c"])
    
    superPrint([1,2,true,false]) //3

 * generic type : 타입의 placeholder, 요구한 대로 signature를 생성해 줄 수 있는 도구 

원래, generic은 자바와 같은 언어에서 재사용 가능한 컴포넌트를 만들기 위해 사용하는 기법 

-> 단일 타입이 아닌 다양한 타입에서 작동할 수 있는 컴포넌트 생성할 수 있음 

-> 구체적인 타입을 지정하지 않고 다양한 인수와 리턴 값에 대한 타입을 처리할 수 있음 

 

 call signature를 작성할 때, 들어오는 확실한 타입을 모를 때 generic을 사용 (함수에 타입을 입력하는 것을 허용) 

 타입스크립트는 제네릭을 처음 인식했을 때. 순서를 기반으로 제네릭 타입을 알게 됨 

 

1) 타입을 유추하도록 알려줌 

2) 타입의 배열이 될 것이라는 것을 인지하고

3) 그 타입중 하나를 리턴

// placeholder를 사용해 콜 시그니쳐가 제네릭을 받는다는 걸 표기
// 함수가 placeholder의 배열을 받고 placeholder 중 하나를 리턴하도록 설정 
type SuperPrint = {
	<TypePlaceholder> (arr : TypePlaceHolder[]): TypePlaceHolder // <T>로도 가능
    }

    const superprint : SuperPrint = (arr) => {
    	arr.forEach(i => console.log(i))
    }
    
    // 여기서 값을 유추하고 placeholder에서 유추한 타입으로 call signature를 보여줌
    const a = superPrint([1,2,3,4]) 
    const b superPrint([true, false, true])
    const c superPrint(["a", "b","c"])
    
    superPrint([1,2,true,false])
728x90