러닝 타입스크립트 | ch 5. 함수

doodoo·2023년 3월 2일
0
post-thumbnail

매개변수

  • 함수의 매개변수 타입은 명시적으로 타입 정보가 선언되지 않으면 알 수 없다(any 타입으로 간주).
  • 타입 애너테이션으로 매개변수의 타입을 선언할 수 있다.

필수 매개변수

타입스크립트는 함수에 선언된 모든 매개변수가 필수라고 가정한다.

function singTwo(first: string, second: string) {
    console.log(first, second);
}

singTwo('Ball and Chain'); // Error
singTwo('I Will Survive', 'Higher Love'); // OK
singTwo('Go Your Own Way', 'The Chain', 'Dreams'); // Error

선택적 매개변수

  • : 앞에 ?를 추가해서 매개변수가 선택적이라고 표시한다.
  • 선택적 매개변수는 항상 암묵적으로 undefined가 될 수 있다.
  • 선택적 매개변수는 항상 마지막에 위치해야 한다.
function singTwo(first: string, second?: string) {
    console.log(first, second);
}

singTwo('Greensleeves'); // OK 
singTwo('Greensleeves', undefined); // OK 
  • 선택적 매개변수는 | undefined를 포함하는 유니언 타입 매개변수와 다르다.
    • 선택적 매개변수는 전달해도 되고 안해도 됨
    • | undefined를 포함하는 유니언 타입은 항상 값이 전달 되어야 함
function singTwo(first: string, second: string | undefined) {
    console.log(first, second);
}

singTwo('Greensleeves'); // Error: Expected 2 arguments, but got 1.
singTwo('Greensleeves', undefined); // OK 

기본 매개변수

  • 기본 매개변수를 선언하면 암묵적으로 함수 내부에 | undefined 유니언 타입이 추가된다.
  • 인수를 전달하지 않거나, undefined를 전달해도 된다.
function singTwo(first: string, second = 0) {
    console.log(first, second);
}

singTwo('Greensleeves'); // OK 
singTwo('Greensleeves', undefined); // OK 
singTwo('Greensleeves', '0'); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.

나머지 매개변수

  • 나머지 매개변수는 배열이라서 끝에 [] 구문이 추가된다.
function singTwo(sing: string, ...songs: string[]) {
    console.log(sing, songs);
}

singTwo('Lady Gaga', 'Bad Romance', 'Just Dance'); 


반환 타입

명시적 반환 타입

  • 변수와 마찬가지로 타입 애너테이션을 사용해 함수의 반환 타입을 명시적으로 선언하지 않는 것이 좋다.
  • 하지만 반환 타입을 명시적으로 선언하는 방식이 유용할때가 종종 있다.
    • 반환값이 많은 함수가 항상 동일한 타입의 값을 반환하도록 강제함
    • 재귀 함수의 반환 타입을 통해 타입을 유추하는 것을 거부함
    • 수백 개 이상의 타입스크립트 파일이 있는 경우 타입 검사 속도를 높일 수 있음
  • 함수 선언 반환 타입은 ) 다음에 위치한다.
  • 화살표 함수의 반환 타입은 => 앞에 위치한다.
// 함수 선언 
function add(a: number, b: number): number {
    return a + b;
}

// 화살표 함수 
const add = (a: number, b: number): number => {
    return a + b;
}


그 외 반환 타입

void 반환 타입

  • void는 함수의 반환 값이 없을때 사용한다.
    • ex) return 문이 없는 함수, 값을 반환하지 않는 return 문을 가진 함수
// void를 반환하는 함수는 값 반환을 허용하지 않음 
function longSong(song: string | undefined): void {
    if(!song) {
        return; // OK
    }

    return true; // Error: Type 'boolean' is not assignable to type 'void'.
}
  • 함수 타입을 선언할 때 void를 사용하면 함수에서 반환되는 모든 값은 무시된다.
  • void는 undefined와 동일하지 않다.
    • void는 함수의 반환 타입이 무시된다는 것을 의미
    • undefined는 반환되는 리터럴 값
  • undefined를 포함하는 대신 void 타입의 값을 할당하려고 하면 타입 오류가 발생한다.
// undefined 대신 void 타입의 값을 할당하려고 하면 타입 오류 발생
function returnVoid(): void {
    return;
}

let lazyValue: string | undefined;

lazyValue = returnVoid(); // Error: Type 'void' is not assignable to type 'string | undefined'.

never 반환 타입

  • 함수가 값을 절대 반환하지 않을때 사용한다.
  • never 반환 함수는 오류를 발생시키거나 무한 루프를 실행하는 함수
  • 함수가 절대 반환하지 않도록 의도하려면 명시적 : never 타입 애너테이션을 추가한다.
function fail(message: string): never {
    throw new Error(`Invariant failure: ${message}`);
}

function workWithUnsafeParam(param: unknown) {
    // param의 타입을 string으로 좁혀 타입스크립트의 제어 흐름 분석을 도와줌
    if(typeof param !== 'string') {
        fail(`param should be a string, not ${typeof param}`);
    }

    param.toUpperCase(); // OK: param type: string 
}


함수 타입

  • 함수 타입 구문은 화살표 함수와 유사하지만 함수 본문 대신 타입이 있다.
  • 콜백 매개변수를 설명하는 데 자주 사용된다.
let add: () => number;

👉 add 변수 타입은 매개변수가 없고 number 타입을 반환하는 함수


함수 타입 괄호

유니언 타입의 애너테이션에서 함수 반환 위치를 나타내거나, 유니언 타입을 감싸는 부분을 표시할 때 괄호를 사용한다.

// 타입: string | undefined 유니언을 반환하는 함수 
let returnStringAndUndefined: () => string | undefined;

// 타입: undefined나 string을 반환하는 함수 
let maybeReturnString: (() => string) | undefined;

매개변수 타입 추론

타입스크립트는 선언된 타입의 위치에 제공된 함수의 매개변수 타입을 유추할 수 있다.

let singer: (song: string) => string;

singer = function(song) {
    // song: string 타입 
    return `Singer: ${song}`;
}

함수 타입 별칭

type StringToNumber = (input: string) => number;

let stringToNumber: StringToNumber;

stringToNumber = (input) => input.length; // OK 


함수 오버로드

주의
함수 오버로드는 복잡하거나 설명이 어려운 함수 타입에 사용하는 최후의 수단.
가능하면 함수 오버로드를 사용하지 않는 것이 좋다.

함수 오버로딩은 동일한 이름에 매개변수만 다른 여러 버전의 함수를 만드는것
👉 하나의 최종 구현 시그니처와 그 함수의 본문 앞에 서로 다른 버전의 함수 이름, 매개 변수, 반환 타입을 선언한다.

// 오버로드 시그니처
function creatDate(timestamp: number): Date;
function creatDate(month: number, day: number, year: number): Date;

// 구현 시그니처 
function creatDate(monthOrTimestamp: number, day?: number, year?: number) {
    return day === undefined || year === undefined 
    ? new Date(monthOrTimestamp)
    : new Date(year, monthOrTimestamp, day);
}

creatDate(554356800); // OK
creatDate(7, 27, 1987); // OK

creatDate(4, 1); // Error: No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments.
  • creatDate() 함수는 1개 또는 3개의 매개변수를 사용해 호출한다. 허용된 수의 인수가 아니라면 오류가 발생한다. (2개의 인수를 허용하는 오버로드 시그니처가 없기 때문)
  • 구현 시그니처는 모든 오버로드 시그니처와 호환되어야 한다.
  • 자바스크립트로 컴파일하면 오버로드 시그니처는 사라진다.

0개의 댓글