TypeScript 함수

김대현·2020년 4월 11일
2

TypeScript 이론 정리

목록 보기
3/5
post-thumbnail

TypeScript 함수

1. 자바스크립트 함수

기명 함수와 익명 함수의 선언

자바스크립트의 함수는 함수의 이름을 명시해 선언하는 기명 함수(named function)와 함수의 이름을 명시하지 않고 사용하는 익명 함수(anonymous function)로 나뉩니다.

myFunction(1, 2); // 함수 선언전 호출 가능
function myFunction(a, b) // 함수 선언
{
  ...
}

기명 함수는 호출될 때 호이스팅이 발생한다. 따라서 함수를 선언하기 전에도, 함수를 선언한 후에도 호출할 수 있다.

result(1, 2); //익명 함수를 선언하기 전에 호출 불가
let result = function(a, b) { return a * b };
result(1, 2); //호출 가능

이와 반대로 익명 함수를 할당해 함수를 호출하면 익명 함수를 할당한 뒤에만 함수를 호출할 수 있도록 호출 시점을 제한할 수 있다.

자바스크립트 함수의 불안전성

자바스크립트는 매개변수의 타입이나 반환 타입은 없지만, 프로그램이 실행될 때 동적으로 타입을 할당해 추론된 타입이 지정된다. (빠른 속도 보장) 그러나 타입이 없기 때문에 런타임때 의도하지 않은 타입 변환이 일어날 수 있다.

function plus(str) {
  return str + 1000;
}
let result = plus("1000");
console.log(typeof result, result); //string 10001000

이러한 이유때문에 타입을 신뢰할 수 없어서 타입을 검사하는 코드와 타입 캐스팅을 수행하는 코드는 필연적이다.

function plus(num) {
  if(typeof num !== "number") {
    num = Number(num);
  }
}

타입 안정성을 갖춘 TypeScript Function

function max(x: number, y: number):number { ... }

타입스크립트는 함수의 매개변수나 반환 타입을 추가해 타입 안정성을 강화한다.

2. 매개변수의 활용

기본 초기화 매개변수

ES6에서 추가된 기본 초기화 매개변수는 함수의 특정 매개변수에 인수가 전달되지 않으면 매개변수에 설정된 초깃값으로 값을 초기화하는 기능이다.

function pow( x: number, y: number = 2): number { ... }

나머지 매개변수 (Rest Parameter)

ES6에서 추가된 특징으로 개수가 정해지지 않은 인수(arguments)를 배열(array)로 받을 수 있는 기능이다. 개수가 정해지지 않은 만큼 순서가 크게 중요하지 않은 여러 요소를 전달하는 데 유용하다.

function colors(a: string, ...rest: string[]) 
{ 
	return a + " " + rest.join(" "); 
}

//colors();
let color1 = colors("red"); //red
let color2 = colors("red", "orange"); //red orange
let color3 = colors("red", "orange", "yellow"); //red orange yellow

선택 매개변수 (Optional Parameter)

선택 매개변수는 변수명 뒤에 물음표를 붙이는 식으로 선언한다. 선택 매개변수를 이용하면 선택 매개변수로 지정한 매개변수는 생략할 수 있다.

function sum(a: number, b?: number): number {
  return a + b;
}
console.log(sum(1));  // NAN

함수 오버로드

함수 오버로드(function 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;
}

가장 일반적인 (general) 함수 (매개변수를 any 타입으로 선언)의 시그니처를 가장 아래에 선언하고 그 위로 구체적인 (speific) 타입을 명시한 함수의 시그니처를 쌓는 방식으로 선언해야 한다.

3. 익명 함수의 이해와 활용

익명 함수와 화살표 함수

화살표 함수(arrow function)는 ES6 표준에 포함된 익명 함수를 좀 더 간략하게 표현할수 있는 방법이다.

() => { };      //매개변수 목록 -> 함수 블록

화살표 함수는 익명 함수로서 매개변수 목록, 화살표, 함수 블록으로 구성된다.

let z1 = ((x,y) => x + y); // return 값이 있음
let z2 = (x,y) => { return x + y; }; //중괄호가 있을때는 return을 써줘야 함

화살표 함수는 익명 함수라서 변수에 할당하고 호출을 해야하지만, 변수에 할당하지 않고 즉시 호출함수(IIF:Immediately Invoked Function)을 이용할 수 있다. 즉시 호출 함수는 코드를 실행하면 별도의 외부 호출 없이 자체적으로 호출되는 함수

let iif = (x => { return x; })(3);

화살표 함수를 filter, find 메서드에 적용

filter 메서드는 배열에서 조건에 맞는 요소를 추출하는 데 사용한다. filter 메서드를 사용한 방법은 for 문을 순회해 조건에 맞는 요소를 추출하는 방법보다 편리하고 유지보수에 좋다. find도 마찬가지

let numberList = [1, 2, 3, 4, 5];
numberList = numberList.filter(n => {
  return n % 2 === 0;
});
console.log(numberList); // [2, 4]

const number = numberList.find(n => n === 2);
console.log(number); // 2

객체 리터럴의 선언과 객체 리터럴 타입의 선언

객체 리터럴(object literal)은 여러 속성과 값을 한 단위로 묶어서 표현할 수 있는 객체이다. 객체 리터럴의 속성은 키(key)가 되고, 값(value)은 숫자나 문자열 뿐만 아니라 사용자가 정의한 객체도 할당할 수 있다. 값을 선언하면서 객체 프로퍼티를 참조하려면 this 키워드를 이용하면 된다.

let person = {
  name: 'Happy',
  hello: function (name2: string) {
    return `Hello, ${this.name} + ${name2}`;
  }
};
console.log(person.hello("world"));  //Hello, HappyWorld

객체 리터럴의 hello 속성에 선언된 함수는 함수 내부의 스코프에서 다른 객체 속성에 접근하려 할 때 코드 어시스트가 동작하지 않는다. 만약 정의한 객체 리터럴 내부에서 다른 프로퍼티를 참조할 일이 많다면 객체 리터럴의 타입을 선언해 내부 참조를 함으로써 코드 어시스트가 동작하게 할 수 있다. 객체 리터럴의 타입은 인터페이스를 이용해 정의한다.

interface PersonType {
  name: string;
  hello(this: PersonType, name2: string): string;
}
let typedPerson: PersonType = {
  name: "Happy",
  hello: function (this: PersonType, name2: string): string {
    let message = `Hello, ${this.name + name2}`;
    return message;
  }
}
console.log(typedPerson.hello("World"));

this 키워드를 활용했기 때문에 객체 리터럴의 프로퍼티를 참조하는 내부 참조 시에 코드 어시스트가 작동하고, 외부에서 hello 함수에 접근할 때도 코드 어시스트가 작동한다.

익명 함수의 함수 타입

익명 함수는 변수에 할당할 수 있다. 익명 함수가 할당된 변수는 타입을 추가할 수 있기 때문에 함수 자체에도 타입이 존재한다는 것을 짐작할 수 있다. 할당한 익명 함수에 매개변수 타입과 반환 타입을 추가할 수 있다.

let myConcat = function (str1: string, str2: string): string { return str1 + str2; };

익명 함수의 매개변수나 반환값에 타입을 지정할 수 있지만, 익명 함수가 구현체이므로 타입을 선언하면 형태가 다소 복잡해진다. 이러한 점을 개선하기 위해 익명 함수에 선언된 타입을 별도로 분리해 함수 타입으로 선언하면, 타입 안정성을 보장하면서도 익명 함수의 타입이 무엇인지 쉽게 파악이 가능하다.

let myConcat: (str1: string, str2: string) => string = (str1, str2) => { return str1 + str2; };
  • 익명 함수의 매개변수나 반환값에 타입을 별도로 분리할 수 있다.
  • 익명 함수에 타입을 추가하지 않아도 함수 타입만으로 익명 함수의 타입 안전성이 보장된다.
  • 익명 함수의 타입이 무엇인지는 함수 타입을 통해 곧바로 확인할 수 있으므로 가독성이 좋아진다.

익명 함수의 타입을 함수 타입으로 분리하면 새로 정의한 타입은 반복적으로 재활용해 사용할 수 있다.

type calcType = (a: number, b: number) => number;

콜백 함수의 타입 선언과 활용

콜백 함수(callback function)또 다른 함수의 매개변수로 전달될 수 있는 함수이다. 여기서 콜백 함수를 전달받는 함수는 콜백 함수보다 상위 처리를 담당하며 고차 함수(higher-order function)라고 불린다. 고차 함수에서 콜백 함수를 인수로 받아서 사용하면 고차 함수 실행(이벤트)이 끝난 다음의 후속 처리를 콜백 함수에서 실행할 수 있다.

function echoFunction(message: string, callback) {
  return callback(message);
}

let responseMessage = echoFunction("hello world!", message => message);
console.log(responseMessage); 	//hello world!
profile
FrontEnd Developer with React, TypeScript

0개의 댓글