본문 바로가기
📌 Front End/└ TypeScript

[TypeScript] 타입스크립트 함수(Function)

by 쫄리_ 2024. 7. 26.
728x90
반응형

함수(Function)

함수는 여러 문장들을 묶어서 실행하는 기능을 갖는데,

함수를 여러번 호출하여 사용할 있기 때문에

함수는 재사용 가능한 코드 블럭의 기본 단위로 볼 수 있다.


함수 기본 구조

TypeScript에서 함수는 function 키워드를 사용하여 정의는데, 

function 뒤에 함수명을 적고 함수명 뒤 괄호 안에 입력 파라미터들을 나열한다. 

입력파라미터는 그 타입을 명시할 수도 있으며, 

함수의 리턴 타입 또한 입력 파라미터 뒤에 : 을 찍은 후 리턴 타입을 명시할 수 있다. 

 

📝 함수 형태

// ▶ 함수
function 함수 (인자:타입) : 리턴타입 {}

// ▶ 화살표 함수
const 변수명 = (인자 : 타입) : 리턴타입 => {}
function 함수명(매개변수1: '매개변수1 타입', 매개변수2: '매개변수2 타입'): '반환 타입'{...}

// ▶ 화살표 함수(arrow function)
let 변수명 = (매개변수1: '매개변수1 타입', 매개변수2: '매개변수2 타입'): '반환 타입' => {...}

// ▶ 기명 함수
function add(x: number, y: number): number {
  return x + y;
}
                                                            
// ▶ 익명 함수
let myAdd = function (x: number, y: number): number {
  return x + y;
};


함수 타입 선언

타입스크립트 함수에서는 총 3가지 타입을 정의할 수 있다.

  • 매개변수 타입
  • 반환(리턴)값 타입
  • 구조 타입

매개변수 타입

타입스크립트의 경우 매개변수:타입 형태로 타입을 선언한다.

function sum(a:number, b:number) {
  return a + b;
}

 

매개변수에서 spread 문법을 사용할 수 있다. (나머지(rest) 매개변수)

function firstElement(...nums:number[]):number {
  return nums[0];
}

 


반환(리턴)값 타입

타입스크립트에서는 반환값에 대한 타입을 정의할 수 있다.

function sum(a:number, b:number):number {
  return a + b;
}

 

만약 반환값의 타입을 정하지 않을 때는 void라고 지정한다.

function func():void {
  console.log('리턴값 없음');
}

 

리턴값을 2개 이상 받고 싶다면?

function A():number[]{
    return [1,2];
}

console.log(A()[0]);    // 1
console.log(A()[1]);    // 2

 


구조 타입

함수 구조 타입도 동일하게 매개 변수 타입과 반환 타입으로 이루어져 있으며, =>로 연결해 줍니다. 
리턴 타입은 함수 구조 타입의 필수적인 부분 이므로 

값을 반환하지 않는 함수라면 비워두는 것이 아니라 void를 사용해 줍니다.

 

📝 함수 구조 타입 형태

(매개 변수1: 매개 변수1 타입, 매개 변수2: 매개 변수2 타입) => 리턴 타입

 

사용예시

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

 

함수 내에서 참조하는 외부 변수는 타입 작성 대상이 아닙니다.

기본적으로 let이라 생각하면됨.

 


매개 변수(파라미터)

타입스크립트에서는 정의된 모든 매개 변수는 필수값으로 간주 되며,

정의되지 않은 매개 변수는 인자로 전달될 수 없습니다.

 

  • 기본값 파라미터 (Default Parameter)
  • 옵셔널 파라미터 (Optional Parameter)
  • 가변 파라미터 (Rest Parameter)
// ▶ 함수 기본값 파라미터(Default Parameter)
function greet(greeting: string, name?: string) {
	// ...
}

// ▶ 함수 옵셔널 파라미터(Optional Parameter)
function greet(greeting: string, name = "Steve") {
	// ? 를 통해 타입을 정의하면 해당 파라미터 값은 넘기지 않아도 됨.
	// ...
}

기본값 매개변수 (Default Parameter)

타입스크립트에서는 매개 변수에 기본값을 설정할 수 있어, 

사용자가 인자에 값을 제공하지 않으면 매개 변수를 기본 값으로 초기화 합니다.

function greet(greeting: string, name = "everyone") {
  return greet + " " + name + "!";
}

greet("Hello", "Steve"); // returns "Hello Steve!"
greet("Hello"); // returns "Hello everyone!"
greet("Hi", "Steve", "Jobs"); // Compiler Error: Expected 1-2 arguments, but got 3.

 


선택 매개변수 (Optional Parameter)

만약, 선택 사항으로 두고 싶은 인자가 있다면 ?를 이용해 아래와 같이 정의할 수 있습니다. 

여기서 주의할 사항은 optional한 매개 변수는 필수적인 매개 변수 보다 앞서 정의될 수 없습니다.

맨 뒤에 작성 할 것

function greet(greeting: string, name?: string) {
  return greet + " " + name + "!";
}

greet("Hello", "Steve"); // returns "Hello Steve!"
greet("Hello"); // returns "Hi undefined!".
greet("Hi", "Steve", "Jobs"); // Compiler Error: Expected 2 arguments, but got 3.

 


가변 파라미터 (Rest Parameter)

함수의 파라미터 갯수가 가변적인 것을 가변 파라미터라 하는데,

예를 들어, 파라미터가 1개일 수도 있고 10개일 수도 있다.

 

TypeScript에서는 가변 파라미터를 Rest Parameter 라고 부르는데,

이는 함수의 파라미터 리스트 중 가장 마지막에 위치해야 한다.

 

가변 파라미터를 지정하는 문법은

파라미터명 앞에 ... 을 붙이면 되고, 타입은 배열로 지정하면 된다.

가변 파라미터가 받을 수 있는 파라미터의 갯수는 0개부터 N개까지 가변적이다.

 

function greet(greeting: string, ...names: string[]) {
  return greet + ' ' + names.join(", ") + '!';
}

greet("Hello", "Steve", "Bill"); // returns "Hello Steve, Bill!"
greet("Hello"); // returns "Hello !"

// 함수 구조 타입
let greetFunc: (greeting: string, ...names: string[]) => string = greet;

 


함수 교환

TypeScript는 function에도 Type을 선언할 수 있다.

타입 지정 대상은 함수로 전달되는 매개변수와 최종 리턴 값이 될 수 있다.

function Pluss(x:number, y: number):number{
    return x+y;
}
function Minus(x:number, y: number):number{
    return x-y;
}

let Func: Function = Pluss;     // 함수 교환
let Func: Function = Minus;     // 함수 교환

console.log(Func(1,2));

객체의 속성과 함수

객체(Object) 안에 함수를 넣을 때 주의사항


📝
객체의 함수 형태

         함수명이 키값 대용으로 사용되기 때문에 function 키워드가 없어야 한다.

         function 키워드 없이 함수를 등록할 수 있다.

const math = {
  sum(a: number, b: number): number {
    	return a + b;
  },
};

 

📝 속성이 함수 표현식 형태

const math = {
  sum: function sum(a: number, b: number): number {
    	return a + b;
  },
};

 

📝 속성이 (리턴을 생략한) 화살표 함수 형태

const math = {
  sum: (a: number, b: number): number => a + b,
};

 

사용예시

let obj: any = {
    b: function B(){
        console.log('C');
    },
    A(): number{
            return 5;
    }
};

console.log(obj.A());   // 5
obj.b();                // C

 

➕ 함수 스스로를 정의할 수 없는 타입을 작성하기 위해서는 

      객체로 감싸는 형태로 타입을 정의해야 한다. 

      객체 리터럴 안에 정의될 때는 속성의 함수 타입을 스스로 지정할 수 없다.


오버로드(Overloads)

타입스크립트에서 오버로드(Overloads)는

함수명은 같지만 매개 변수의 타입과 반환 타입이 다른 여러 함수를 가질 수 있는 것을 말합니다.

단, 매개 변수의 수는 동일해야 합니다.

 

컴파일 시간에 가장 적합한 오버로드를 선택해 컴파일 하기 때문에

런타임 비용이 발생하지 않는 특징이 있습니다.

// 함수 선언
function add(a:string, b:string): string;
function add(a:number, b:number): number;

// 함수 구현
function add(a: any, b:any): any {
    return a + b;
}

add("Hello ", "Steve"); // returns "Hello Steve" 
add(10, 20); // returns 30

 


This

자바스크립트에서 함수를 호출할 때

매개 변수로 전달되는 인자값 뿐만 아니라 arguments 객체 및 this가 함수 내부로 암묵적으로 전달 됩니다.

즉, this는 함수가 호출될 때 설정되는 변수 입니다.

함수 내 this는 호출 시점에 따라 전역 객체를 참조하거나, 

undefined가 되어버려 원하는 context를 참조하지 않게 되기도 합니다. 

 

이를 해결하기 위해 

call, apply 또는 bind 메서드를 사용하여 this를 직접 명시해 주거나, 

함수 생성 시 this를 참조하는 화살표 함수(arrow function)을 사용해 줄 수 있습니다. 


타입스크립트에서는 위에 언급한 패턴으로 

this를 바인딩 하더라도 함수 내부에서 this의 타입을 알 수 없기 때문에 this는 any 타입이 됩니다.

 

타입스크립트에서 this

아래와 같이 매개 변수의 첫 번째 자리에 가짜(fake) 매개 변수 this를 전달해 명시해 줄 수 있습니다.

function 함수명(this: 'this 타입') {
  //...
}

 


사용예시

interface Person {
    name: string;
};

const person: Person = { 
    name: "Steve"
};

function greet(this: Person, greeting: string) {
  return greeting + " " + this.name + "!"; 
}

greet.call(person, 'Hello') // returns "Hello Steve!"

콜백에서의 this

콜백 함수(callback function)는 다른 함수의 인자로 전달될 수 있는 함수입니다. 

콜백 함수의 경우 콜백을 호출하는 라이브러리가 일반 함수처럼 실행할 것이기 때문에 this는 undefined가 됩니다. 

따라서 콜백으로 함수가 전달되었을 때 this를 구분해 주어야 하는 경우 아래와 같이 강제해 줄 수 있습니다.

 

this: void 라고 정의해 주었으므로, 

addClickListener 의 onclick 콜백 함수는 함수 내부에서 this를 필요로 하지 않는 함수 입니다.

interface UIElement {
  addClickListener(onclick: (this: void, e: Event) => void): void;
}
class Handler {
  info: string;
  onClickGood(this: void, e: Event) {
    console.log('clicked');
  }
}
let handler = new Handler();
uiElement.addClickListener(handler.onClickGood);
class Handler {
  info: string;
  onClickBad(this: Handler, e: Event) {
    // 위의 `UIElement` 인터페이스에 `this: void`로 정의했기 때문에 에러 발생
    console.log('clicked');
  }
}
let handler = new Handler();
uiElement.addClickListener(handler.onClickBad); // error!


class Handler {
  info: string;
  onClickBad(this: void, e: Event) {
    // `this`의 타입이 `void`이기 때문에 `this`를 사용할 수 없어 에러 발생
    this.info = e.message;
  }
}
let handler = new Handler();
uiElement.addClickListener(handler.onClickBad); // error!

 

 

만약, 콜백 함수 내부에서 this를 사용하고 싶다면, 화살표 함수를 사용할 수 있습니다.

class Handler {
  info: string;
  onClickGood = (e: Event) => {
    this.info = e.message;
  };
}

 

 


728x90
반응형