08 함수타입
Handbook
1. 함수에 타입 선언 하기
함수에 타입을 선언하는 것은 매개변수와 반환값에 타입을 지정하는 것
1.1. 함수 선언문
- 함수 선언: 함수의 매개변수와 반환 타입을 명시합니다.
1function add(a: number, b: number): number {2 return a + b;3}4console.log(add(1,2))1.2. 함수 표현식
1//표현식 함수로 매개변수 타입 및 반환값 타입 지정2{3 const add = function (a: number, b: number): number {4 return a + b;5 };6 console.log(add(1, 2));7}8//화살표 함수로 매개변수 타입 및 반환값 타입 지정9{10 const add: (a: number, b: number) => number = function (a, b) {11 return a + b;12 };13 console.log(add(1, 2));14}15//화살표함수를 화살표함수로 타입지정16{17 //const add=()=>{return}18 //함수내 매개변수와 반환값에 직접지정19 const add = (a: number, b: number): number => {20 return a + b;21 };22 add(10, 20);23 //함수의 식별자에 지정24 const add2: (a: number, b: number) => number = (a, b) => {25 return a + b;26 };27 add2(10, 20);28}29 //리턴생략30 const add3: (a: number, b: number) => number = (a, b) => a + b;31 add3(10, 20);32}아래의 코드를 화살표함수로 타입지정해보자
1 const print = (a) => {2 return `${a}님 안녕하세요`3 };4 console.log(print('멤버1'));1 //const print: (a: string) => string = (a) => `${a}님 안녕하세요`;2 const print = (a: string): string => `${a}님 안녕하세요`;3 console.log(print('멤버1'));1//void: return 없을때2{3// const print = (a, b) => {4 const print = (a: string, b: number): void => {5 console.log(`${a}님 ${b}번째 방문이네요`);6 };7 print('회원', 2);8}1 //매개변수,반환값없음,표현식2 const print2 = function (): void {3 console.log('no return');4 };5 print2();6
7 //화살표, 변수에 지정8 //const print3: () => void = function () {9 //const print3: () => void = () => {10 const print3 = (): void => {11 console.log('no return');12 };13 print3();1.3. 매개변수와 인자의 길이가 다른 경우
1.3.1. 옵셔널리터럴
- 아래의 경우 리턴에서 에러가 난다 매개변수 c는 값이 없으므로 undefined 가 할당되어 있기 때문이다.
1//optional literal2{3 //const sum = (a: number, b: number, c: number) => {4 const sum = (a: number, b: number, c?: number): number => {5 return a + b + c;6 };7 sum(10, 20);8}- 변수c의 값이 없을 경우에 대한 로직을 추가해야 한다.
1 //return a + b + c;2 return a + b + (c || 0);1.3.2. 매개변수에 초깃값을 할당하여 지정
- 아래와 같이 작성하면 a,b 는 number 타입선언
1 function sum(a = 0, b = 0): number {2 return a + b;3 }- 화살표함수
1const sum1 = (a = 0, b = 0): number => a + b;- 아래의 경우처럼 변수에 타입을 지정할때는 초기값에 의한 선언이 안됨
1//오류2const sum3: (a = 0, b = 0) => number = (a, b) => a + b;3
4const sum3: (a: number, b: number) => number = (a, b) => a + b;1.4. 나머지연산자에 사용
- 아래와 같은 경우에 타입을 지정해보자
1{2 function fn(...rest):void {3 console.log(rest);4 }5 fn(1,2,3,4)6}1{2 function fn(...rest: number[]) {3 console.log(rest);4 }5 fn(1, 2, 3, 4);6}- 튜플의 선언
1 function fn1(...rest: [number, string, number, string]):void {2 console.log(rest);3 }4 fn1(1, 'a', 2, 'b');화살표로 변경
1 //const fn2 = (...rest: [number, string, number, string]): void => console.log(rest);2 const fn2: (...rest: [number, string, number, string]) => void = (...rest) => console.log(rest);1.5. 콜백함수
1.5.1. 간단한 콜백
- 아래의 경우는 어떻게 타입을 선언해야 할까?
1{2 function print(cb) {3 cb('user');4 }5 print((name) => console.log(name));6}- 아래와 같이 작성할수 있다
1{2 function print(cb: (name: string) => void) {3 cb('user');4 }5 print((name) => console.log(name));6}화살표
1 {2 const print = (cb: (name: string) => void) => cb('user');3 print((name) => console.log(name));4 }5 {6 const print: (cb: (name: string) => void) => void = (cb) => cb('user');7 print((name) => console.log(name));8 }1.5.2. 복잡한 콜백
- case1. 아래의 콜백 함수는 조금 더 복잡한 형태이다. 이 함수에 대해 타입을 선언해보자
1{2 function compareNumber(a, b, result) {3 if (a === b) {4 result('equal');5 } else {6 result('not equal');7 }8 }9
10 compareNumber(1, 1, (result) => {11 console.log(`The numbers ar ${result}`);12 });13}1{2 function compareNumber(a: number, b: number, result: (result: string) => void) {3 if (a === b) {4 result('equal');5 } else {6 result('not equal');7 }8 }9
10 compareNumber(1, 1, (result) => {11 console.log(`The numbers ar ${result}`);12 });13}- case2.
1{2 function array(arr, compare, cb) {3 for (let i of arr) {4 if (compare(i)) cb(i);5 }6 console.log('홀수가 없네요');7 }8 array(9 [1, 2, 3, 4],10 (i) => i % 2 > 0,11 (i) => console.log(`${i}가 홀수예요`)12 );13}1 //function array(arr: number[], compare: (i: number) => boolean, cb: (i: number) => void) {2// const array = (arr: number[], compare: (i: number) => boolean, cb: (i: number) => void) => {3const array: (arr: number[], compare: (i: number) => boolean, cb: (i: number) => void) => void = (arr, compare, cb) => {4 for (let i of arr) {5 if (compare(i)) cb(i);6 }7 console.log('홀수가 없네요');8 }9 array(10 [1, 2, 3, 4],11 (i) => i % 2 > 0,12 (i) => console.log(`${i}가 홀수예요`)13 );1.5.3. never
결코 반환될수 없는 값. 함수가 예외를 발생시키거나 프로그램 실행을 종료함을 의미
https://www.typescriptlang.org/ko/docs/handbook/2/functions.html#never
1 //에러처리시2 function fail(msg: string): never {3 throw new Error(msg);4 }5
6 //유니온에 아무것도 없음7 function fn(x: string | number) {8 if (typeof x === "string") {9 // do something10 } else if (typeof x === "number") {11 // do something else12 } else {13 x; // 'never' 타입이 됨!14 }15 }16 //무한루프17 function infinityLoop(): never {18 while (true) {}19 }2. 함수 타입문제
2.1.
문제 1: 두 수의 합을 구하는 함수
다음과 같은 add 함수가 있습니다. add 함수는 두 개의 숫자(a, b)를 받아 그 합을 반환합니다. 적절한 타입을 붙여서 함수 정의를 하고, 두 개의 숫자를 넘겨서 호출하고 결과를 출력해보세요.
문제 2: 이름을 받아 인사하는 함수
greet 함수는 사용자의 이름을 받아 "Hello, \{name\}!"을 출력하는 함수입니다. name 파라미터는 필수로 받아야 하며, 적절한 타입을 붙여서 함수 정의를 하고, 함수를 호출해보세요.
문제 3: 숫자 배열을 받아 합을 구하는 함수
sumAll 함수는 여러 개의 숫자를 받아 그 합을 반환하는 함수입니다. sumAll 함수는 rest parameter를 사용하여 배열의 길이에 관계없이 숫자들을 받을 수 있어야 합니다. 함수 호출 후 결과를 출력해보세요.
문제 4: 기본값을 설정한 덧셈 함수
sum 함수는 두 숫자를 더하는 함수입니다. a는 필수 매개변수로 받고, b는 기본값을 0으로 설정합니다. 이 함수에 타입을 지정하고 호출해보세요.
문제 5: 두 수를 곱하는 함수
multiply 함수는 두 숫자(a, b)를 받아 그들의 곱을 반환하는 함수입니다. 매개변수와 반환값의 타입을 적절히 지정하고, 함수를 호출하여 결과를 출력해보세요.
문제 6: 문자열과 숫자를 결합하는 함수
concatStringAndNumber 함수는 문자열(a)과 숫자(b)를 받아 그 합을 문자열로 반환합니다. 매개변수의 타입을 적절히 지정하고, 함수를 호출해보세요.
문제 7: 옵셔널 파라미터를 사용한 인사 함수
greet 함수는 이름을 받아 인사말을 반환합니다. name 파라미터는 필수로 받되, message 파라미터는 옵셔널 파라미터로 받습니다. message가 없으면 기본값 "Welcome"을 사용해야 합니다. 이 함수의 타입을 지정하고, 호출해보세요.
문제 8: 숫자 배열의 최대값을 구하는 함수
findMax 함수는 숫자 배열을 받아 그 배열의 최대값을 반환하는 함수입니다. 이 함수의 타입을 지정하고 호출해서 배열의 최대값을 출력해보세요.
문제 9: 단일 숫자를 두 배로 만드는 함수
double 함수는 하나의 숫자를 받아 그 값을 두 배로 만들어 반환하는 함수입니다. 이 함수의 타입을 지정하고 호출하여 결과를 출력해보세요.
2.2.
문제 1: 여러 개의 숫자 배열을 받아 합을 구하는 함수
문제 설명: sumAllNumbers 함수는 여러 개의 숫자 배열을 인자로 받아 각 배열의 합을 구하여 반환하는 함수입니다. rest parameter와 map을 사용하여 여러 배열을 처리하고 결과를 반환해야 합니다.
문제 2: 숫자를 받아 그 값을 두 배로 만드는 함수
문제 설명: doubleValue 함수는 숫자를 인자로 받습니다. 숫자라면 두 배를 반환합니다. 함수의 반환값 타입을 지정해보세요.
문제 3: 두 숫자 배열을 받아 각 배열의 곱을 구하는 함수
문제 설명: multiplyArrays 함수는 두 개의 숫자 배열을 받아 각 배열에서 해당 인덱스의 숫자를 곱한 값을 새로운 배열로 반환합니다. 배열의 길이가 다르면 짧은 배열에 맞춰서 곱셈을 해야 합니다.
문제 4: 두 개의 배열을 받아 교차된 값을 반환하는 함수
문제 설명: intersection 함수는 두 개의 배열을 받아 교차된 값들만 반환하는 함수입니다. 두 배열에서 겹치는 값들을 찾아 반환해보세요.
(배열의 값은 숫자 배열로 한정합니다.)
문제 5: 객체의 필드 값에 따라 출력 형식을 다르게 하는 함수
문제 설명: formatInfo 함수는 객체를 받아, name 필드가 존재하면 "Name: \{name\}"을 출력하고, age 필드가 존재하면 "Age: \{age\}"를 출력합니다. 매개변수 타입을 지정하고 호출해보세요.
문제 6: 두 문자열을 합쳐서 출력하는 함수
문제 설명: combineStrings 함수는 두 개의 문자열을 받아 합쳐서 반환하는 함수입니다. 두 문자열의 순서를 바꿀 수 있도록 하며, 적절한 타입을 지정하여 함수를 정의하고 호출해보세요.
문제 7: 배열의 각 값을 제곱하여 새로운 배열을 반환하는 함수
문제 설명: squareArray 함수는 숫자 배열을 받아 그 배열의 각 값에 대해 제곱을 계산하여 새로운 배열을 반환합니다.
문제 8: 문자열과 숫자가 주어졌을 때, 그 둘을 더하여 문자열로 반환하는 함수
문제 설명: addStringAndNumber 함수는 문자열과 숫자를 인자로 받아 두 값을 더하여 문자열로 반환하는 함수입니다. 적절한 타입을 지정하여 함수를 정의하고 호출해보세요.
문제 9: 타입이 서로 다른 두 값을 비교하는 함수
문제 설명: compareValues 함수는 숫자와 문자열을 받아 두 값을 비교하여 결과를 출력하는 함수입니다. 숫자가 크면 "Number is larger", 문자열의 길이가 길면 "String is larger"를 반환하도록 하세
3. 타입오퍼레이터 문제
3.1.
1. 유니언 타입 사용하기: 값 출력하기
문제:string 또는 number 타입의 값을 받아서 해당 값을 출력하는 함수 printValue를 작성하세요. 이 함수는 입력된 값이 string이면 문자열 그대로 출력하고, number이면 숫자 그대로 출력해야 합니다.
1// 코드를 작성하세요2. 유니언 타입을 사용한 조건 처리
문제:
주어진 입력 값이 string이면 그 길이를, number이면 2배 값을 반환하는 함수 doubleOrLength를 작성하세요. 함수는 string 타입이면 문자열의 길이를, number 타입이면 그 숫자의 두 배 값을 반환해야 합니다.
1// 코드를 작성하세요3. 인터섹션 타입 사용하기: 객체 합치기
문제:name과 age 속성을 가진 사람 객체와 jobTitle과 salary 속성을 가진 직장인 객체가 있을 때, 이 두 객체를 합쳐서 새로운 객체를 반환하는 함수 mergeObjects를 작성하세요. 결과 객체는 이름(name), 나이(age), 직업(jobTitle), 월급(salary)을 포함해야 합니다.
1// 코드를 작성하세요4. 유니언 타입을 사용한 배열 처리
문제:
배열이 number[] 또는 string[]일 때, 배열의 첫 번째 요소를 반환하는 함수 getFirstElement를 작성하세요. 배열이 비어 있을 경우 undefined를 반환해야 합니다. 반환값은 배열의 첫 번째 요소 타입과 동일해야 합니다.
1// 코드를 작성하세요5. 유니언 타입을 사용한 값 비교
문제:
두 값을 받아서 두 값이 같으면 true를, 다르면 false를 반환하는 함수 isEqual을 작성하세요. 입력 값은 string 또는 number일 수 있으며, 두 값이 동일하면 true를 반환하고, 다르면 false를 반환해야 합니다.
1// 코드를 작성하세요6. 인터섹션 타입을 활용한 필드 업데이트
문제:name과 age 속성을 가진 객체에 address를 추가하는 함수 updateAddress를 작성하세요. address는 string 또는 undefined일 수 있습니다. address가 전달되지 않으면 기존 객체에 address는 포함되지 않아야 합니다.
1// 코드를 작성하세요2function updateAddress(){}3console.log(updateAddress({name: 'John', age: 20}, "seoul")); // { name : "John", age: 20, address: "seoul"}4console.log(updateAddress({name: 'John', age: 20})); // { name : "John", age: 20}7. 유니언 타입을 사용한 함수 반환 타입
문제:
두 값을 받아서 그 중 더 큰 값을 반환하는 함수 maxValue를 작성하세요. 입력 값은 number 또는 string일 수 있으며, 숫자일 경우 그대로 반환하고, 문자열일 경우 길이가 더 긴 문자열을 반환합니다. 만약 두 값이 같으면 그 값을 반환하세요.
1// 코드를 작성하세요2
3
4console.log(maxValue(10, 20)); // 205console.log(maxValue("apple", "banana")); // banana6
7console.log(maxValue(10, 10)); // 108console.log(maxValue('a', 'a'); // 'a'9console.log(maxValue('a', 'b'); // 'b'8. 유니언 타입으로 함수 오버로딩하기
문제:getValue 함수는 string 또는 number를 받아서 string 값을 반환합니다. number인 경우에는 그 값을 string으로 변환하고, string인 경우 그대로 반환합니다.
힌트: 함수를 정의하고, 오버로드 시그니처를 추가하세요.
1// 코드를 작성하세요9. 인터섹션 타입을 활용한 객체 합치기 (다양한 속성 포함)
문제:name, age 속성을 포함하는 객체와 email 속성을 포함하는 객체를 합쳐서 새로운 객체를 반환하는 createContact 함수를 작성하세요. 두 객체를 합친 결과는 이름, 나이, 이메일을 포함해야 합니다.
1// 코드를 작성하세요2
3const person = { name: 'john', age: 20 } ;4const contact = { email: 'email@gmail.com' };5console.log(createContact(person, contact)); // {name: 'john', age:20, email: 'email@gmail.com' }10. 유니언 타입을 사용한 나이 체크
문제:age 값을 받아서, string일 경우 숫자로 변환하여 처리하고, number일 경우 그대로 반환하는 getAge 함수를 작성하세요.