[ 3D Web : Front&Back_Type Script ]
타입스크립트 : 타입스크립트 함수 타입 공부하기.
∇ Front & Back _ TypeScript : 타입스크립트 함수 타입 공부하기.
목 차
1. TS의 함수 표현
1-1 일반적인 함수 정의
1-2 Call Signature(함수 타입)
2. TS의 매개변수 표현
2-1 선택적 매개변수
2-2 매개변수 초기화
2-3 나머지(rest) 매개변수
2-4 네임드 파라미터
3. TS의 콜백/ 중첩 / 고차 함수
3-1 콜백 함수
3-2 중첩 함수
3-3 고차 함수
4. TS의 this 표현
4-1 명시적 this
5. TS의 함수-오버로딩
Ⅰ. TS의 함수 표현.
※ TS에서 함수를 표현하는 방법은 여러가지가 존재한다고 합니다. (머리가 아플 정도)
TS로 백*프론트 모두 사용하고, Nest 프레임워크에서도 언어로 활용되는 만큼, 진짜 제대로 짚고 넘어가보겠습니다.
Ⅰ - ⅰ. 일반적인 함수 정의
- TS(JS기반)에서는 일반적으로 함수를 표현하는데에 크게 3가지 표현방법이 있습니다.
: "함수 선언식" // "함수 표현식" // "화살표 함수"
[ + 여기에, 매개변수 & 리턴값*타입 만 지정해주면 되니 그렇게 난해하지 않습니다. ]
§ 함수 선언식.
//* 함수 선언식
function myFunc1(x: number, y: number): number {
return x + y;
}
§ 함수 표현식.
//* 함수 표현식
let myFunc2 = function (x: number, y: number): number {
return x + y;
};
§ 화살표 함수.
//* 화살표 함수
let myFunc3 = (x: number, y: number): number => {
return x + y;
};
Ⅰ - ⅱ. Call Signature (함수 타입)
위쪽 코드에서도 나오긴 했는데,
변수를 선언할 때, 문자열을 string, 정수배열을 number[]로 표현했듯이
"함수를 표현하는 타입( ≡함수에서 반환하는 값의 타입) 을 미리 선언 가능합니다.
§ "함수 타입"을 미리 선언하고 뒤에 함수식을 붙여넣게되면,
함수 아규먼트에서 타입을 또다시 선언하지 않아도 된다는 특징을 가집니다.
//* 변수에 미리 함수 타입을 지정
let myFunc4: (arg1: number, arg2: number) => number;
myFunc4 = function (x, y) {
return x + y;
}; // 미리 변수에 함수 타입을 지정했기에 대입하는 함수식에 타입을 쓰지않아도 된다.
//* 위의 과정을 한줄로 표현
let myFunc5: (arg1: number, arg2: number) => number = (x, y) => {
return x + y;
};
**주의할 점!
- 위에서 설명한 화살표 함수와 헷갈리지 않게 조심해야 합니다.!!
- 함수 표현식에선, 함수의 리턴 타입을 콜론(:)으로 표현했는데
따로 함수 타입을 선언할 때는 화살표로 리턴 타입을 표현한다는 점에서 주의가 필요합니다!
∫ 함수 타입과 화살표 함수를 섞어서 사용하기.
let myFunc5: (arg1: number, arg2: number) => number = (x,y) => {return x + y; };
*이런 방식의 이점 4가지,
1. 타입 안정성 향상.
- 함수 타입을 명시적으로 선언함으로써, TS의 정적 타입 검사를 최대한 활용.
- 코드의 안정성을 높이고 런타임 오류를 줄이는 데 도움.
2. 코드 가독성 개선.
- 함수의 목표를 명확히 정의함으로써, 다른 개발자들이 함수의 입*출력 타입을 쉽게 이해 가능.
3. 화살표 함수의 간결성
- 화살표 함수를 사용함으로써, 더 간결한 문법으로 함수를 정의 가능.
4. this 바인딩 예측 가능성.
- 화살표 함수는 자신만의 this를 생성하지 않아서, 렉시컬 스코프의 this를 사용하므로
this 관련 버그를 줄일 수 있습니다.
▣ " type 별칭 " 및 "인터페이스" 역시 개별적으로 함수타입을 선언하여 사용될 수 있습니다.
[ 인터페이스는 함수 타입을, 화살표가 아닌 콜론(:)으로 표현합니다 ]
//* type 리터럴로 함수 타입을 지정
type Add1 = (x: number, y: number) => number;
let myFunc6: Add1 = (x, y) => {
return x + y;
};
//* 인터페이스로 함수 타입을 지정
interface Add2 {
(x: number, y: number): number;
}
let myFunc7: Add2 = (x, y) => {
return x + y;
};
Ⅱ. TS의 매개변수 표현.
☆ TS에서는 함수의 인자를 모두 필수 값으로 간주합니다.
= > 함수의 매개변수를 설정하면,
심지어 인자값이 undefined나 null 같은 쓸모없는 값이라 할지라도, 인자로 넘겨야하며,
컴파일러에서는 정의한 매개변수 값이 제대로 넘어왔는지 확인합니다.
function sum(a: number, b: number): number {
return a + b;
}
sum(10, 20); // 30
sum(10, 20, 30); // error, too many parameters
Ⅱ - ⅰ. 선택적 매개변수.
** 만약에, 순수한 JS를 사용할 때처럼, 유연하게
정의된 매개변수의 개수와 정확히 일치하는 만큼 인자를 넘기지 않아도 되게 만들고 싶다면,
선택적(optional) 키워드인 물음표(?)를 활용해서 아래와 같이 정의 가능합니다.
ex) ? 키워드를 사용해, 'b' 를 선택적 매개변수로 지정.
(b가 받을 인수가 없어도 에러가 발생하지 않습니다)
function sum(a: number, b?: number): number {
return a + b;
}
sum(10, 20); // 30
sum(10); // 타입 에러 없음
≡ ? 키워드 사용은 유니온 타입 ( | undefined ) 을 추가하는 것과 같다고 볼 수 있습니다.
function sum(a: number, b: number | undefined): number {
return a + b;
}
sum(10, 20); // 30
sum(10); // 타입 에러 없음
++ Null 병합 연산(??) 사용하여서, null 또는 undefined인 경우 '0'을 반환하도록 지정하는 식으로도 처리 가능.
function add(a: number, b?: number, c?: number): number {
return a + (b ?? 0) + (c ?? 0);
}
add(1, 2, 3); // 6
add(1, 2); // 3
add(1); // 1
◎ 단, '선택적 매개변수'를 사용할 때 주의할점은
선택적 매개변수가 이외의 함수 인자 앞단에 위치하면 안된다는 것입니다.
[ 선택적 매개변수는 무조건 뒤로 위치 !]
function sum(b?: number, a: number): number {
return a + (b ?? 0);
}
Ⅱ - ⅱ. 매개변수 초기화.
○ 매개변수 초기화는 JS의 ES6문법과 동일합니다.
○ 기본값을 할당한, 매개변수의 함수 타입은
"옵셔널 파라미터(선택적 매개변수)" 가 적용된 것을 확인 가능합니다.
≒ 매개변수에 기본 값이 있으면, 매개변수에 값을 할당하지 않아도 된다는 의미.
● 기본 값이 있으면, 굳이 인자 타입을 선언해주지 않아도 됩니다 == "TS의 타입추론"
function sum(a: number, b = 100): number {
// 매개변수 기본 값이 있으면 굳이 인자 타입을 선언하지 않아도 된다 (타입 추론)
return a + b;
}
sum(10, undefined); // 110
sum(10); // 110
sum(10, 10) // 20
Ⅱ - ⅲ. 나머지(rest) 매개변수.
※ JS에서 사용되는 '스프레드 매개변수' 역시 직접 타입만 잘 지정하면 TS에서도 문제없이 사용 가능합니다.
function sum(a: number, ...nums: number[]): number {
const totalOfNums = 0;
for (let key in nums) {
totalOfNums += nums[key];
}
return a + totalOfNums;
}
☆다만, !
TS에서 strict 모드를 true로 하고 사용하기 때문에
JS의 'arguments 예약어'는 사용될 수 없다는 점을 유의!
Ⅱ - ⅳ. 네임드 파라미터.
◎ 'named parameters'는 함수 아규먼트 부분 전체를 객체로 감싸주고, 그 뒤에 타입을 정의해주는 방식.
function getText({ name, age = 15, language }: { name: string; age?: number; language?: string }): string {
const nameText = name.substr(0, 10);
const ageText = age >= 35 ? 'senior' : 'junior';
return `name: ${nameText}, age: ${ageText}, language: ${language}`;
}
getText({ name: '홍길동', age: 11, language: 'kor' });
getText({ name: '홍길동' });
☆ 네임드 파라미터는 함수의 argument 갯수가 많을 때 유용하게 사용가능합니다.
:: 아규먼트의 타입 정보들을 뒤로 위치시킴으로서, 한 눈에 함수 아규먼트 구성을 볼 수 있기 때문.
Ⅲ. TS의 콜백 / 중첩 / 고차 함수.
Ⅲ - ⅰ 콜백 함수.
:: 콜백 인자의 타입을 정해줄 때는,
위에서 언급했던 call signiture(함수 타입)으로 지정해주면 됩니다.
const logging = function (s: string) {
console.log(s);
};
const init = (callback: (arg: string) => void) => {
console.log('callback start');
callback('yes!');
console.log('callback end');
};
init(logging);
/*
callback start
yes!
callback end
*/
Ⅲ - ⅱ 중첩 함수.
:: 함수 타입 선언만 잘 해놓으면 간단히 중첩해서 사용이 가능합니다.
const calc = (value: number, cb: (arg: number) => void) => {
const add = (a: number, b: number) => a + b; // 화살표 함수
function mul(a: number, b: number) { // 함수 표현식
return a * b;
}
let result = mul(add(3, 4), value);
cb(result);
};
calc(2, (output) => console.log(output)); // 14
Ⅲ - ⅲ 고차 함수.
:: 고차 함수(high order function) == "함수를 반환하는 함수"
const add = (a: number) => {
return (b: number) => {
return a + b;
};
};
// 곧바로 실행
console.log(add(3)(8)); // 11
// 한 번 걸쳤다가 실행
const first = add(3);
console.log(first(8)); // 11
Ⅲ. TS의 this 표현.
☆ 함수를 다루는데 있어서 가장 중요한 내용 중 하나가 바로 "this" 키워드 입니다.
Ⅳ - ⅰ 명시적 this.
interface Cat {
name: string;
}
const cat: Cat = {
name: 'Lucy',
};
function someFn(greeting: string) {
console.log(`${greeting} ${this.name}`); // Error - 'this'에는 형식 주석이 없으므로 암시적으로 'any' 형식이 포함됩니다.
}
someFn.call(cat, 'Hello'); // 위에 에러가 나서 실행이 안됨
=> someFN 메소드는 전역 렉시컬 스포크에 위치하기에, this에 any 오류가 나타나게 됩니다.
++ 이 경우, this 타입을 명시적으로(explicitly) 선언 가능합니다.
== someFn 이라는 메소드의 this의 타입은 명시적으로 ICat 인터페이스를 가리키게 함으로써
타입을 명시해 오류를 없앨 수 있습니다.
=>> 가짜 매개변수로 this를 선언하면 됩니다.
interface ICat {
name: string
}
const cat: ICat = {
name: 'Lucy'
};
function someFn(this: ICat, greeting: string) {
console.log(`${greeting} ${this.name}`); // ok
}
someFn.call(cat, 'Hello'); // Hello Lucy
Ⅴ. TS의 함수 오버로딩
◎ "오버로딩" 이란, Java등의 언어에서는 매개변수는 다르지만, 내역은 동일한 함수를 말하는 것입니다.
◎ TS의 함수-오버로드(OVerloads) 역시 이름은 같지만,
정확히 말하자면 매개변수 타입과 반환 타입이 다른 여러 함수를 가질 수 있는 것을 말합니다.
◎ TS의 함수-오버로드(OVerloads) 선언법은 중괄호{} 없는 함수를 실제 함수 위에다가 사용해주면 됩니다.
function add(a: string, b: string): string; // 오버로드 함수 선언
function add(a: number, b: number): number; // 오버로드 함수 선언
function add(a: any, b: any): any { // 오버로드 함수 실행부 (any를 써준다)
return a + b;
}
add('hello ', 'world~');
add(1, 2);
§ 오버로드 함수에서의 any 표현은 TS에서 허용됩니다.
위 코드를 보면, 함수 실행부에서의 인수와 리턴 타입에 any를 사용했는데,
컴파일러는 오버로드 함수 선언부의 타입들만 보고 함수를 판단하기 때문에
실행부에 any를 사용하는게 문제가 되지 않습니다.
'Front_End [JS기반] > 타입스크립트' 카테고리의 다른 글
[ 3D Web : Front&Back_Type Script ] 타입스크립트 : 타입 선언의 종류 총정리. (2) | 2024.11.20 |
---|---|
[ 3D Web : Front&Back_Type Script ] 타입스크립트의 타입 선언 (0) | 2024.11.18 |
[ 3D Web : Front&Back_Type Script ] 타입스크립트 트랜스파일링 설정 : ' tsconfig ' 의 옵션 총 정리. (2) | 2024.11.18 |
[ 3D Web : Front&Back_Type Script ] 타입스크립트 : 트랜스파일링이란 (0) | 2024.11.18 |
[ 3D Web : Front&Back_Type Script ] 타입스크립트의 정의*동작원리*특징 (1) | 2024.11.18 |