공부공부/TS

[typescript 핸드북] 03. 함수

고생쨩 2024. 2. 19. 09:30
728x90

typescript 핸드북 학습내용 정리
https://typescript-kr.github.io/pages/the-handbook.html

함수

함수 (Function)

// 기명 함수
fucntion add(x, y) {
  return x + y;
}

// 익명 함수
let myAdd = function(x, y) { return x + y };
// 함수는 함수 외부의 변수를 참조는 경우를, 변수를 캡처(capture) 한다고 함. 
let z = 100;

function addToZ(x, y) {
  return x + y + z;
}

함수 타입 (Function Types)

함수의 타이핑 (Typing the function)

function add(x: number, y: number): number {
    return x + y;
}

let myAdd = function(x: number, y: number): number { return x + y };

반환 타입은 생략가능

함수 타입 작성하기 (Writing the function type)

함수의 타입은 매개변수의 타입과 반환 타입이 있음

let myAdd: (x: number, y: number) => number =
    function(x: number, y: number): number { return x + y; };
// 매개변수명은 별 상관없음
let myAdd: (baseValue: number, increment: number) => number =
    function(x: number, y: number): number { return x + y; };
  • ‘화살표 표기’( => )로 반환타입 정의. 값을 반환 안하면 void로 표기
  • 매개변수 타입과 반환 타입만이 함수 타입을 구성됨.

    캡처된 변수는 타입에 반영되지 않음.

타입의 추론 (Inferring the types)

방정식의 한쪽에만 타입이 있더라도 타입을 알아낼 수 있음

// myAdd는 전체 함수 타입을 가집니다
let myAdd = function(x: number, y: number): number { return  x + y; };

// 매개변수 x 와 y는 number 타입을 가집니다
let myAdd: (baseValue: number, increment: number) => number =
    function(x, y) { return x + y; };

이러한 타입 추론 형태를 “contextual typing” 이라 부름.

선택적 매개변수와 기본 매개변수 (Optional and Default Parameter)

// 기본 매개변수는 다 들어와야함
function buildName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // 오류, 너무 적은 매개변수
let result2 = buildName("Bob", "Adams", "Sr.");  // 오류, 너무 많은 매개변수
let result3 = buildName("Bob", "Adams");         // 정확함
// 선택적 매개변수는 ? 붙여서
function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

let result1 = buildName("Bob");                  // 지금은 바르게 동작
let result2 = buildName("Bob", "Adams", "Sr.");  // 오류, 너무 많은 매개변수
let result3 = buildName("Bob", "Adams");         // 정확함

기본-초기화 매개변수 : 유저가 값을 제공하지 않거나 undefined로 했을 때에 할당될 매개변수의 값을 정해 놓을 수도 있음.

function buildName(firstName: string, lastName = "Smith") {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // 올바르게 동작, "Bob Smith" 반환
let result2 = buildName("Bob", undefined);       // 여전히 동작, 역시 "Bob Smith" 반환
let result3 = buildName("Bob", "Adams", "Sr.");  // 오류, 너무 많은 매개변수
let result4 = buildName("Bob", "Adams");         // 정확함

모든 필수 매개변수 뒤에 오는 기본-초기화 매개변수는 선택적으로 처리되며, 선택적 매개변수와 마찬가지로 해당 함수를 호출할 때 생략할 수 있음.

// 기본-초기화 매개변수가 필수 매개변수보다 앞에 오게 된다면 사용자가 명시적으로 undefined 를 전달해 주어야 기본-초기화 매개변수를 볼 수 있음
function buildName(firstName = "Will", lastName: string) {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // 오류, 너무 적은 매개변수
let result2 = buildName("Bob", "Adams", "Sr.");  // 오류, 너무 많은 매개변수
let result3 = buildName("Bob", "Adams");         // 성공, "Bob Adams" 반환
let result4 = buildName(undefined, "Adams");     // 성공, "Will Adams" 반환

나머지 매개변수 (Rest Parameters)

…으로 정의

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

// employeeName 은 "Joseph Samuel Lucas MacKinzie" 가 될것입니다.
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

생략 부호는 나머지 매개변수가 있는 함수의 타입에도 사용됨

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;

this

  • 매개변수에서 this를 받고 싶지 않으면 void 타입 지정
function f(this: void) {
    // 독립형 함수에서 `this`를 사용할 수 없는 것을 확인함
}
  • 메서드에서는 화살표 함수를 쓸것
class Handler {
    info: string;
    onClickGood = (e: Event) => { this.info = e.message }
}

오버로드 (Overloads)

  • JavaScript는 본질적으로 매우 동적인 언어입니다. 하나의 JavaScript 함수가 전달된 인자의 형태에 따라 다른 타입의 객체들을 반환하는 것은 흔한 일.
  • 오버로드 목록으로 동일한 함수에 다중 함수 타입을 제공할 수 있음.
    오버로드 목록은 컴파일러가 함수 호출들을 해결할 때 사용하는 것임.
let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
    // 인자가 배열 또는 객체인지 확인
    // 만약 그렇다면, deck이 주어지고 card를 선택합니다.
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // 그렇지 않다면 그냥 card를 선택합니다.
    else if (typeof x == "number") {
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);
  1. 오버로드 목록에서 첫 번째 오버로드를 진행하면서 제공된 매개변수를 사용하여 함수를 호출하려고 시도함.
  2. 만약 일치하게 된다면 해당 오버로드를 알맞은 오버로드로 선택하여 작업을 수행함.
  3. 이러한 이유로 가장 구체적인 것부터 오버로드 리스팅을 하는 것이 일반적.
  • 위 예제에서 function pickCard(x): any는 오버로드 목록에 해당되지 않음을 유의, 그래서 두 가지 오버로드만을 가집니다: 객체를 받는것 하나와 숫자를 받는 것 하나. 다른 매개변수 타입으로 pickCard를 호출하는 것은 오류가 발생합니다.

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.