tech.junha.kr

[Typescript] 함수 사용하기 (parameter, optional, rest, overloading)

1. 함수 선언

• 매개변수와 리턴값의 타입을 선언 후 사용하면 된다.

function func1(name: string): string {
	return 'hello ${name}';
}

const func2 = function (name: string): string {
	return 'hello ${name}';
}

const func3 = (name: string): string => {
	return 'hello ${name}';
}

const world4 = (name: string): string => 'hello ${name}';

2. 매개변수 수 일치

• 함수에 주어진 인자의 수는 함수가 기대하는 매개변수의 수와 일치해야 한다.

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

const result1 = buildName("Bob"); // Error: Expected 2 arguments, but got 1
const result2 = buildName("Bob", "Adams", "Sr."); // Error: Expected 2 arguments, but got 3
const result3 = buildName("Bob", "Adams")

3. Optional Parameter

• ?를 붙여 선택적 프로퍼티를 만들수도 있다.

• 선택적 매개변수들은 필수 매개변수 뒤에 위치해야한다.

function buildName(firstName: string, lastName?: string) {
	if (lastName) return firstName + " " + lastName;
	else return firstName;
}

let result1 = buildName("Bob");
let result2 = buildName("Bob", "Adams");
let result3 = buildName("Bob", "Adams", "Sr."); // Error: Expected 2 arguments, but got 3

4. Rest Parameter

• 컴파일러는 생략 부호(...) 뒤의 인자 배열을 빌드해 함수에서 사용할 수 있다.

• 나머지 매개변수는 매개변수의 수를 무한으로 취급한다.

• 아무것도 넘겨주지 않을 수도 있다.

function buildName1(firstName: string, ...restOfName: string[]) {
	// restOfName = [ 'Samuel', 'Lucas', 'MacKinzie' ]
	return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName1("Joseph", "Samuel", "Lucas","MacKinzie");
// "Joseph Samuel Lucas MacKinzie"

5. Function Overloading

• 파라미터의 형태가 여러 케이스에 대응하는 같은 이름을 가진 함수를 만들 때 사용한다.

• 함수의 다형성(다양한 형태)을 지원한다.

함수 오버로딩을 위해 해야할 것 2가지

  1. 선언 : 함수가 어떤 파라미터 타입들을 다룰 것인지 선언

  2. 구현 : 각 파라미터 타입에 대응하는 구체적인 코드를 작성

1. 함수 오버로딩 선언

  • 함수의 이름이 같아야 한다.
  • 매개변수의 순서는 서로 같아야 한다.
  • 반환 타입이 같아야 한다.
class User {  // ✅
  constructor(private id: string) {}
  setId(id: string): string;
  setId(id: number): string;
}

class User { // ❌
  constructor(private id: string) {}
  // 선언 시에 에러는 나지 않지만 오버로딩 함수 정의 시에 에러;
  setId(id: string): void;
  setId(id: string): number; // 반환 타입 다름;
  setId(radix: number, id: number): void; // 인수 순서 다름
}

2. 함수 오버로딩 구현

1) 매개변수의 개수가 같을 때

class User {
  constructor(private id: string) {}
  setId(id: string): void;
  setId(id: number): void;
  setId(id: string | number): void {
    this.id = typeof id === 'number' ? id.toString() : id;
  }
}

2) 매개변수의 개수가 다를 때

class User {
  constructor(private id: string) {}
  setId(id: string): void;
  setId(id: number, radix: number): void;
  setId(id: string | number, radix?: number): void {
    this.id = typeof id === 'number' ? id.toString(radix) : id;
  }
}

3. 함수 오버로딩으로 바꾼 예시

Before

  • 파라미터의 타입만 다르고 비슷한 코드가 반복되고 있는 코드에서 함수 오버로딩을 적용해보자
const addZero = (num: string) => (num > 9 ? '' : '0') + num;

function formatDate(date: Date, format = 'yyyyMMdd'): string {
  const yyyy = date.getFullYear().toString();
  const MM = addZero(date.getMonth() + 1);
  const dd = addZero(date.getDate());
  return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}

function formatDateString(dateStr: string, format = 'yyyyMMdd'): string {
  const date = new Date(dateStr);
  const yyyy = date.getFullYear().toString();
  const MM = addZero(date.getMonth() + 1);
  const dd = addZero(date.getDate());
  return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}

function formatDateTime(datetime: string, format = 'yyyyMMdd'): string {
  const date = new Date(datetime);
  const yyyy = date.getFullYear().toString();
  const MM = addZero(date.getMonth() + 1);
  const dd = addZero(date.getDate());
  return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}

After

const addZero = (num: string) => (num > 9 ? '' : '0') + num;

function formatDate(date: Date, format = 'yyyyMMdd'): string;
function formatDate(date: number, format = 'yyyyMMdd'): string;
function formatDate(date: string, format = 'yyyyMMdd'): string;

function formatDate(date: string | Date | number, format = 'yyyyMMdd'): string {
  const dateToFormat = new Date(date);
  // … dateToFormat validation …
  const yyyy = dateToFormat.getFullYear().toString();
  const MM = addZero(dateToFormat.getMonth() + 1);
  const dd = addZero(dateToFormat.getDate());
  return format.replace('yyyy', yyyy).replace('MM', MM).replace('dd', dd);
}

4. 제네릭과 차이점

타입 추론 시점용도의 범위
제네릭타입이 사용되는 시점제네릭 타입
인터페이스
클래스
함수 등
함수 오버로딩타입을 선언하는 시점함수
메서드