웹 구현시 자주 사용되는 함수는 타입스크립트로 크게 아래 3가지의 타입을 볼 수 있다.
- 함수의 파라미터(매개변수) 타입
- 함수의 반환 타입
- 함수의 구조 타입
함수의 기본적인 타입 선언
타입스크립트의 함수 선언 방법을 이해하기 위해서 자바스크립트 함수를 먼저 살펴보자
function sum(a, b) {
return a+b;
}
//위의 js함수에 타입을 부여하면
function sum(a: number, b: number): number {
return a+b;
}
→ 기존 js 함수의 선언방식에서 매개 변수와 함수의 반환값에 타입을 추가하였다.
함수의 반환 값에 타입을 정하지 않을때는 'void'를 사용한다.
함수의 인자
타입스크립트에서는 함수의 인자를 모두 필수값으로 간주한다. 따라서 함수의 매개변수를 설정하면 undefined 혹은 null 이라도 인자로 넘겨야한다. 그리고 컴파일러에서 정의된 매개변수값이 넘어왔는지 확인한다. 달리말하자면 정의된 매개변수 값만 받을 수 있고 추가로 인자를 받을 수 없다.
function sum(a: number, b: number): number {
return a+b;
}
sum(40, 50); //90
sum(40, 50, 54); //error, too many parametres
sum(54); //error, too few parameters
function sum(a: number, b?: number): number {
return a+b;
}
sum(40, 50); //90
sum(40, 50, 54); //error, too many parametres
sum(54); // 타입에러없음
→ 다음과같이 ?를 이용하면 매개변수의 갯수와 받는 인자가 달라도 타입에러가 뜨지 않는것을 볼 수있다.
매개 변수 초기와는 ES6 문법과 동일하다.
function sum(a: number, b='54'): number {
return a+b;
}
sum(46, undefined); //100
sum(46, 47, 48); //error, too many parameters
sum(46); //100
REST 문법이 적용된 매개변수
ES6 문법에서 지원하는 REST 문법은 타입스크립트에서 아래와 같이 사용 가능하다.
function sum(a: number, ...nums: number[]): number {
const totalsOfNums = 0;
for (let key in nums) {
totalOfNums += nums[key];
}
return a + totalOfNums;
}
this
타입스크립트에서도 자바스크립트의 this가 잘못 사용되었을때 감지가 가능합니다.
// 타입스크립트에서 this 가 가리키는 것을 명시하려면 다음과 같은 문법을 사용
function 함수명(this: 타입) {
//...
}
interface Vue {
el: string;
count: number;
init(this: Vue): () => {};
}
let vm: Vue = {
el: '#app',
count: 10,
init: function(this: Vue) {
return () => {
return this.count;
}
}
}
let getCount = vm.init();
let count = getCount();
console.log(count); //10
→ 위의 코드를 타입스크립트로 컴파일 했을때 --noImplicitThis 옵션이 있더라도 에러가 발생하지 않는다.
(엄격한 타입-확인 옵션 중 "noImplicitThis: true"는 this키워드가 any타입일 경우 에러. )
콜백에서의 this
일반적인 상황에서의 this와 다르게 콜백으로 함수가 전달되었을 때의 this를 구분해줘야할때가 있다.
interface UIElement {
//'this: void'코드는 함수에 'this'타입을 선언할 필요가 없다,는 의미.
addClickListener(onClick: (this: void, e: Event) => void): void;
}
class Handler {
info: string;
onClick(this: Handler, e:Event) {
//'UIElement' 인터페이스의 스펙에 'this'가 필요없다고 했지만, 사용했기때문에 에러발생.
this.info = e.message;
}
}
let handler = new Handler();
UIElement.addClickListener(handler.onClick); //error!
/* UIElement 인터페이스의 스펙에 맞춰 'Handler'를 구현하기 위해서 아래와 같이 변경한다. */
class Handler {
info: string;
onClick(this: void, e: Event) {
//'this'의 타입이 void 이므로 여기서 'this'를 사용할 수 없다.
console.log('clicked!');
}
}
let handler = new Handler();
UIElement.addClickListener(handler.onClick);
클래스의 메서드 방식으로 선언하는 것과 변수에 화살표 함수를 연결하는 것의 차이점
1. arrow 함수 : App.ArrowFunc로 정의
2. 클래스 method: App.prototype.Func 로 정의
즉, console.log(App.prorotype)을 실행시킨다면 결과값은 => "{constructor: f, Func: f}"
클래스 method는 공유 메소드로 상속받은 컴포넌트에서 참조할 수 있지만, arrow 함수는 그렇지 못하다.
class method는 프로토타입에 정의되어있으며 모든 인스턴스에서 공유도된다. n개의 상속받은 class가 있는 경우, 각각 동일한 method를 공유한다. 따라서 해당 method를 사용하면, 여전히 n번의 method를 호출하지만 동일한 프로토 타입을 호출하는것이다.
프로토타입 전역에서 동일한 메소드를 여러 번 호출하면 Javascript엔진이 이를 최적화 할 수 있다고한다.
반면에 클래스 멤버변수에 할당된 arrow함수에 대해 n개의 클래스를 만들면 이 n개의 클래스 들과 상응하여 n개의 함수를 만들게 된다.
'Javascirpt, Typescript' 카테고리의 다른 글
ts 공부하기) 인터페이스 (0) | 2023.10.24 |
---|---|
추가공부) JavaScript & TypeScript의 this (0) | 2023.10.23 |
ts공부하기) 타입스크립트 기본 타입 (0) | 2023.10.20 |
ts공부하기) nest.js에서 필요한 필수 typescript (2) | 2023.10.19 |
ts 공부하기) 타입 애너테이션 (0) | 2022.12.29 |