[TS] 함수에서 타입 작성 방법

정(JJeong)·2023년 2월 2일
0

TypeScript 익히기

목록 보기
5/10
post-thumbnail

함수에서는 어떻게 작성하고 쓸까? 거두절미하고 바로 보자.

📌 매개변수 type설정

optional parameter

function hello (name: string) {
  return `Hello ${name || "world"}`
}

const result = hello()	// error가 뜬다.

위 예시를 보면 name이라는 매개변수를 갖는 hello함수를 만들었고, name이 없을 때 대신 나타내줄 값도 ||를 통해 표시했다.

그런데 매개변수값 없이 helle()만 부르면 에러가 뜬다.
TS는 보다 정확히 알려줘야한다는 것. 때문에 name값 앞에 옵션으로 만들어줄 ?를 붙여야 한다.

function hello(name?: string) {...}

참고: default 정하기

위처럼 옵션처리가 아니어도 JS에서 쓰듯이 default처리를 해주면 된다.

function hello (name="world") {
  return `Hello ${name}`
}

optional parameter의 위치

function hello (name: string, age?: number):string {
  if (age !== undefined) {
    return `Hello, ${name}. You are ${age}.`
  } else {
    return `Hello, ${name}.`
  }
}

const sam = hello("Sam");
const samAge = hello("Sam", 33);

console.log(sam);
console.log(samAge);

위 함수는 name은 string으로 받는 필수적인 매개변수이고, age는 number type을 가지는 매개변수로써 선택적으로 받는다. 그리고 string을 리턴한다.

그런데 위에서 옵션인 age를 앞에서 작성하면? 어떻게 될까?

function hello (age?: number, name: string):string {
  // ...
}

빨간 밑줄이 그어진다. 즉 필수 매개변수가 앞에 작성되어야 하는 것이다.
만약 위처럼 옵션인 age를 앞에 굳이 쓰고 싶다면 다음과 같이 직접 명시적으로 지정해서 바꿔줘야한다.

function hello (age: number | undefined, name: string):string {
  if (age !== undefined) {
    return `Hello, ${name}. You are ${age}.`
  } else {
    return `Hello, ${name}.`
  }
}

const sam = hello(undefined, "Sam");
const samAge = hello(33, "Sam");

console.log(sam);
console.log(samAge);


나머지 매개변수(rest parameter)

function add (...nums) {
  return nums.reduce((result, num) => result + num, 0);
}

add(1,2,3);					// 6
add(1,2,3,4,5,6,7,8,9,10)	// 55

위 함수는 나머지 매개변수를 활용해주고 있다. 나머지 매개변수는 여러 개로 들어오는 매개변수를 배열로 처리 가능하게 해준다.

나머지 매개변수 정리글 ← 링크 클릭시 이동

무엇으로? 배열로! 그렇기 때문에 다음처럼 배열로 type을 설정해준다.

function add (...nums: number[]) {
  // ...
}


📌 함수에서 this의 타입 설정?

interface User {
  name: string;
}

const Sam: User = {name:'Sam'}

function showName() {
  console.log(this.name)
}

const a = showName.bind(Sam);
a();

위 코드를 보면 a를 선언하고 할당할 때 bind를 이용해 thisSam객체로 강제하고 있다. 그렇기 때문에 log에는 "Sam"이 찍힐 것이다.

bind에 대한 것인 요기 링크로 이동 !

그런데 showName함수에서 this에 빨갛게 밑줄이 간다. 그 이유는 this에 타입이 결정되지 않았기 때문이다.
그럼 어떻게 설정해줘야할까?

this 타입설정 방법

function showName(this:User) {
  console.log(this.name)
}

위처럼 함수의 매개변수 첫번째 자리에 this의 타입을 설정해주면 된다.
만약 매개변수가 있다면? 그저 똑같이 제일 앞에 써주면 된다.

function showName(this:User, age:number, gender:'m'|'f') {
  console.log(this.name, age, gender)
}

const a = showName.bind(Sam);
a(33, 'm');

주의할 점은 보이는 매개변수가 세개라고 해서 세개의 값을 필요로 하는 것이 아니라는 것이다. 위에서 this는 넣어줄 값이 아니기 때문이다.



📌 함수의 overload

interface User {
  name: string,
  age: number
}

function join (name: string, age: number|string): User | string {
  if (typeof age === "number") {
    return {
      name,
      age,
    };
  } else {
    return "나이는 숫자로 입력해주세요.";
  }
}

위 예시 코드를 보면 에러표시가 뜨지 않아 문제가 없어보인다. 그렇다면 이를 실행해보면 어떨까?

const sam: User = join("Sam", 30);			// error
const jain: string = join("Jane", "33");	// error

위 코드를 써보려 하면 변수명에 빨간 밑줄이 간다. 이유가 무엇일까?
그 이유는 각 변수들에 작성해준 type에 확신이 없기 때문이다.

이게 무슨 말이냐??
join함수를 보면 매개변수 age의 타입이 두 종류가 가능하도록 설정되어 있다.
그리고 함수 안에서 어떤 type의 age가 들어왔냐에 따라 분기를 나눈다.

즉, 함수 자체에서는 이 함수의 return이 User로 될지 string이 될지 정해지지 않았기 때문에 변수 samjane입장에서는 나를 User, string으로 미리 지정해 놓기엔 스스로 확신이 안든다! 뭐 요런 의미이다.

설사 뒤에 할당한 join함수의 매개변수의 값이 작성되어 있어도 정적언어이기에 동작된 뒤에 정해질 return의 타입따위 난 모른다! 뭐 이런게 아닐까? 내 스스로 해석해본 약간 뇌피셜식 풀이이다. ㅎㅎ

그렇담 이때는 어떻게 해야하느냐? 이때 쓰는게 overload이다.


overload(오버로드) 작성

interface User {
  name: string,
  age: number
}

// overload 작성
function join (name: string, age: number): User;
function join (name: string, age: string): string;

function join (name: string, age: number|string): User | string {
  if (typeof age === "number") {
    return {
      name,
      age,
    };
  } else {
    return "나이는 숫자로 입력해주세요.";
  }
}

아주 간단하다. 매개변수의 개수나 타입에 따라 다른 방식의 동작 결과를 내는 함수의 경우, 그 경우를 직접 나눠서 같은 함수를 작성해주면 된다.

신기타 신기해~



profile
2년차 응애 FE 개발자입니다👶

0개의 댓글