TypeScript에 대해서 정리해 봄 (2) - function

Designated Hitter Jack·2023년 11월 11일
0

SW 사관학교 정글

목록 보기
36/44
post-thumbnail

토부 스카이트리라인

functions

call signature

함수 위에 마우스를 올렸을 때 (hover) 나타나는 것.
어떻게 함수를 호출해야 하는 것인지 알려준다.

const add1 = (a:number, b:number) => a+b
//이런 함수를 작성할때에는 인수가 무슨 타입인지 알려줘야 한다.

type Add = (a:number, b:number) => number
//미리 함수 인수의 타입과 return 값의 타입을 알려준다.
//add 함수의 call signature를 이렇게 쓸 수 있다.

const add2: Add = (a, b) => a+b
//함수를 구할 때 앞서 쓴 call signature를 가져온다면 
//인수의 타입을 다시 선언하지 않아도 된다.

overloading

function overloading 또는 method overloading

//call signature는 이런 식으로도 쓸 수 있다.
type Add ={
	(a: number, b: number) : number
}
//overloading 때문에 이런 식으로 써야하는 경우가 존재한다.

overloading 은 한 함수가 서로 다른 여러 개의 call signature를 가지고 있을 때 발생한다.

type Add = {
    (a:number, b:number) : number
    (a:number, b:string) : number
}

const add: Add = (a, b) => {
    if (typeof b === "string") return a;
    return a + b;
}
//Next.js 를 사용할 때 많이 보게 될 오버로딩 예시 코드
//Push 에 path가 들어오는지, Config이 들어오는지에 따라 달라지는 
//call signature를 미리 선언하게 된다.
type Config = {
    path: string,
    state: object
}

type Push = {
    (path: string): void
    (config: Config): void;
}

const push: Push = (config) => {
    if (typeof config === "string") {
        console.log(config);
    } else {
        console.log(config.path);
    }
}

call signature 의 parameters 개수가 서로 다른 경우

type Add ={
    (a: number, b: number): number
    (a: number, b: number, c: number): number
}
//마지막 파라미터를 optional로 표시하고, 타입을 따로 지정해야 함
const add:Add = (a, b, c?:number) => {
    return a + b;
}

polymorphism

//배열 내 요소들을 하나씩 프린트하는 함수
type SuperPrint = {
    (arr: number[]):void;
    (arr: boolean[]):void;
    (arr: string[]):void; //이런식으로 사용하는 건 너무 번거롭다.
}

const superPrint: SuperPrint = (arr) => {
    arr.forEach((item) => {
        console.log(item);
    })
}

superPrint([1,2,3]);
superPrint([true, false, false]);
superPrint(["a", "b", "c"]);
superPrint([1, 2, true, false]); //error

이런 걸 피하기 위해 generic(일종의 type의 placeholder)을 사용한다.
call signature를 작성할 때 들어올 인자의 concrete type을 모를 경우.
<>를 사용하여 이 안의 글자가 generic임을 표시한다.

type SuperPrint = {
		<TypePlaceholder>(arr: TypePlaceholder[]):void;
}

const superPrint: SuperPrint = (arr) => {
    arr.forEach((item) => {
        console.log(item);
    })
}

superPrint([1,2,3]);
superPrint([true, false, false]);
superPrint(["a", "b", "c"]);
superPrint([1, 2, true, false]);

타입스크립트가 이미 설정된 <TypePlaceholder>를 실제 변수의 타입을 보고 call signature를 이에 맞게 수정한다.

generic recaps

//몇번째 인자에 generic을 사용할건지도 정할 수 있다.
type SuperPrint = {
    <T,M>(arr: T[], b:M):void;
}

const superPrint: SuperPrint = (arr) => {
    arr.forEach((item) => {
        console.log(item);
    })
}

superPrint([1,2,3], 'x');
superPrint([true, false, false], 1);
superPrint(["a", "b", "c"], false);
superPrint([1, 2, true, false], []);

generic을 다르게 사용하는 경우

function superPrint<V>(a: V[]) {
    return a[0];
}

superPrint([1,2,3]);
superPrint([true, false, false]);
superPrint(["a", "b", "c"]);
superPrint([1, 2, true, false]);
type Player<E> = {
    name: string;
    extraInfo: E;
}

type NicoExtra = {
    favFood: string;
}
type NicoPlayer = Player<NicoExtra>;

const nico: NicoPlayer = {
    name: "Nico",
    extraInfo: {
        favFood: "kimchi"
    }
}

const lynn:Player<null> = {
    name: "Lynn",
    extraInfo: null
}

type arrNumbers = Array<number>;

let a:arrNumbers = [1,2,3,4,5];

function printAllNumbers(arr: Array<number>) {
    arr.forEach(console.log);
}
profile
Fear always springs from ignorance.

0개의 댓글