[TypeScript] 함수 타입
[TypeScript] 함수 타입
타입스크립트 함수 타입
함수
- 매개 변수와 반환 값의 타입을 지정해주는 것
- 함수 선언문, 함수 표현식, 화살표 함수의 방식이 존재
반환 값의 타입
- 함수의 결과로 내보내는 return의 타입을 의미
- 결과를 받는 변수까지 타입을 지정하는 것은 드묾
void
⇒ 아무것도 반환하지 않음
1 2 3 4
function greet(): void { console.log("Greet!"); } greet();
number
⇒ 숫자 값을 반환
1 2 3 4 5
function sum(n1: number, n2: number): number { return n1 + n2; } const res = sum(10, 20); console.log(res);
다양한 함수 형태
- 매개 변수와 반환 값의 타입에 따라, 다양한 함수 형태를 지정
string → void
1 2 3 4
function printValue(value: string): void { console.log(value); } printValue("A");
number[] → number
1 2 3 4 5 6 7 8 9 10 11 12 13
function add(numbers: number[]): number { return numbers.reduce((res, num) => res + num, 0); } const result = add([1, 3, 5]); console.log(result); // ... 연산자 사용 function add(...numbers: number[]): number { return numbers.reduce((res, num) => res + num, 0); } const result = add(1, 3, 5); console.log(result);
{ } → void
1 2 3 4
function printObj(userObj: { name: string }): void { console.log(userObj.name); } printObj({ name: "jaegeon" });
함수 표현 방식
함수 선언문
function() {…}
함수 표현식
const f1 = function() {…}
- 함수 표현식은 함수 선언문과 다르게, 다음과 같은 형식을 가진다.
함수 자체에 매개 변수와 반환 값의 타입을 지정해주는 방식
1 2 3 4 5
const sum = function sum(n1: number, n2: number): number { return n1 + n2; } const res = sum(10, 20); console.log(res);
변수에 함수의 매개 변수와 반환 값의 타입을 지정해주는 방식
1 2 3 4 5
const sum: (a: number, b: number) => number = function sum(n1, n2) { return n1 + n2; } const res = sum(10, 20); console.log(res);
- 해당 방식은 변수에 타입을 지정했으므로,
굳이 함수 자체에 타입을 지정하지 않아도 됨. - 또한, 변수에 타입을 지정할 때 나타내는 변수명도 변경 가능.
- 해당 방식은 변수에 타입을 지정했으므로,
화살표 함수
const f1 = () ⇒ {…}
예시
1 2 3 4 5 6 7
const sum: (n1: number, n2: number) => number = (n1, n2) => n1 + n2; const res = sum(10, 20); console.log(res); // 다른 표현 방법 const sum = (n1: number, n2: number): number => n1 + n2;
유니언 타입
| (파이프기호)
- 유니언 타입이라 불리며, 타입을 복수개 지정이 가능함.
예시
1 2 3 4 5 6
function printValue(value: number | string): void { console.log(value); } printValue(10); // number도 올 수 있고 printValue("a"); // string도 올 수 있음!
→ 주의사항: 유니언 타입을 중첩해서 사용할 때, 괄호로 묶는 범위를 유의한다!
Type Guard: 타입을 좁혀주는 행위
특정 타입에 따라, 결과물을 출력하거나 반환하고 싶으면,
typeof와 조건문을 활용하여 타입을 좁혀줌.1 2 3 4 5 6 7
function printValue(value: number | string): void { if (typeof value === "number") console.log(value.toFixed(0)); else console.log(value); } printValue(10.123); // number일 때, 소수점 자릿수 숫자 없애기 printValue("a"); // 그 외의 경우, 그대로 출력
반환 값의 타입에도 중복 지정 가능 → 타입 좁혀주기도 가능.
1 2 3 4 5 6
const sum = (n1: number | string, n2: number | string): number | string => { if (typeof n1 === "number" && typeof n2 === "number") return n1 + n2; else return `${n1}${n2}`; }; console.log(sum(10, 20)); // 둘 다 number 이므로 더해줌 console.log(sum("A", "B")); // 그 외의 경우는 연결 연산
→ 주의사항: 타입을 좁혀줄 때, 예외인 타입이 없게 조건문을 작성한다.
→ 주의사항: 타입이 정해져 있어도,
해당 타입의 값이 안 넘어올 수 있는 경우도 고려해야 한다!
void vs never
void
- 아무 값도 반환하지 않음 → 함수에서 반환 값이 없음!
never
절대 반환하지 않음 → 무한 반복 or 에러 발생 시에 사용!
1 2 3 4 5 6 7 8
let obj: Record<string, never> = {}; function throwError(message: string): never { throw new Error(message); // 에러 발생 } function infinitLoop(): never { while (true) {} // 무한 반복 }
→ 의미상 비슷하여, 혼용하여 사용할 수 있으나, 구분할 줄 알아야 함!
함수 오버로드
- 함수가 복수 개의 타입의 인자에 대해 다른 동작을 할 수 있게 함.
- 구현문 이외에, 오버로드를 정의하고 → 타입에 따라 여러개 정의 가능!
- 함수 선언문에서만 사용할 수 있음! (함수 표현식, 화살표 함수 사용 X)
예:
number로 반환되는 값에 대해, 다음과 같이 수행[기존에는 수행 X]
1 2 3 4 5 6 7
function sum(n1: number | string, n2: number | string): number | string { if (typeof n1 === "number" && typeof n2 === "number") return n1 + n2; else return `${n1}${n2}`; } const res1 = sum(1.2, 2.3); console.log(res1); // 3.5 console.log(res1.toFixed(0)); // error 발생
[오버로드를 사용하면, 정상 수행]
1 2 3 4 5 6 7 8 9 10 11
function sum(n1: number, n2: number): number; function sum(n1: string, n2: number): string; function sum(n1: number, n2: string): string; function sum(n1: string, n2: string): string; function sum(n1: number | string, n2: number | string): number | string { if (typeof n1 === "number" && typeof n2 === "number") return n1 + n2; else return `${n1}${n2}`; } const res1 = sum(1.2, 2.3); console.log(res1); // 3.5 console.log(res1.toFixed(0)); // 정상적으로 동작 (결과: 4)
→ 주의사항: 역시, 예외인 타입이 없게 작성한다.
타입 단언
- 함수 오버로드 방식 이외에, 다음 방법을 사용할 수 있음
나온 결과 값에
as를 사용하여 타입을 단언할 수 있음1 2 3 4 5 6 7
function sum(n1: number | string, n2: number | string): number | string { if (typeof n1 === "number" && typeof n2 === "number") return n1 + n2; else return `${n1}${n2}`; } const res1 = sum(1.2, 2.3) as string; console.log(res1); console.log(res1.toFixed(0));
옵셔널 파라미터 ?
- 옵셔널 파라미터
?를 붙이면, 옵셔널 속성이 된다. 옵셔널 속성: 해당 속성에 해당하는 값이 와도 되고, 안와도 된다.
1 2 3 4 5 6 7
function printUserInfo(name: string, age?: number): void { if (name && age) console.log(`${name}, ${age}`); else console.log(`${name}`); } printUserInfo("jaegeon", 26); printUserInfo("jeongsue"); // age가 안와도 정상동작
→ 주의사항: 앞에 오는 파라미터에 단독으로 옵셔널 파라미터를 붙일 수 없다!
This post is licensed under CC BY 4.0 by the author.