[Typescript] 복습 - (1)

yongkini ·2023년 2월 7일
0

TypeScript

목록 보기
9/11
post-custom-banner

Typescript 복습 - (1) ES6에서 추가된 문법 복습

Typescript와 이전 JS(ECMAScript)와의 관계 [Typescript > ESNext(ES6) > ES5]

: 우리가 흔히 아는 ES5, ES6 는 포함 관계가 명확하다. 즉, ES5에 없는 문법이 ES6에 있고, ES6로 코딩을 했을 경우에 결국엔 ES5로 트랜스파일링을 해줘야한다. 그러면 같은 원리로 Typescript도 ES6의 문법을 포함함과 동시에(당연히 ES5도 포함) 타입 기능이 추가된 것이다. 그리고 Typescript도 앞서 말한 것과 마찬가지로 결국 프로젝트에서 쓸 때 ES5로 트랜스파일링을 해줘야한다. 앞서 ES6를 트랜스파일링 할 때는 바벨을 주로 사용하고, 타입스크립트를 트랜스파일링 할 때는 타입스크립트 컴파일러를(여기서 컴파일러는 원래 텍스트를 바이너리로 변환할 때 쓰는 용어지만 앞서 말한 트랜스파일링과 동일한 의미로 쓴다) 사용한다.

** 이런걸 보면 결국 타입스크립트는 런타임에서는 어떠한 영향도 없는 언어이다. 즉, 실제 런타임에서는 JS 로 트랜스파일링된 파일이 실행되지, 실행되는 순간에는 타입스크립트 파일은 없는거다.

ESNext의 주요 문법 다시 보기

  • 비구조화 할당(Destructuring) : 그렇다면, 먼저, 구조화는(Structuring)는 뭘까?. 뭔가를 구조화 한다.. 말이 너무 추상적이다. 코드를 통해 살펴보면,
const myName = 'yongki';
const myAge = 31; 
const myHeight = '177cm';

위에는 나의 정보를 바탕으로 변수를 선언 및 할당한 것이다. 이 때, 이 정보는 구조화 됐다고 할 수 없다. 왜냐하면 위와 같이 해놓으면 사실 저렇게 세줄의 코드를 연속으로 써놨기 때문에 나름 체계가 있다고 생각되지만, 각각 다른 줄에 쓴다면 저 세개가 같은 정보(나의 정보)라고, 즉, 범주화된 혹은 구조화된 정보라고 생각할 수 없다. 따라서, 위의 정보를 다음과 같이 구조화 해보자.

const myInform = {
	name : 'yongki',
    age : 31,
    height : '177cm'
}

위와 같이 정보를 구조화(structuring) 하고 타입으로 지정해두면, 비슷한 유형의 변수를 쉽게 만들 수 있고, 코드의 기능 확장이 이전보다 수월해진다. 그리고 무엇보다 이건 개인적인 시각이지만, 하나의 범주 내에 속해있다는 체계성이 잡힌다고 생각된다. 앞서 말한 타입은 다음과 같이 해주면 될 것이다.

interface IPerson {
	name : string
    age : number
    height : string
}

위와 같이 타입을 지정해주면, 해당 정보가 체계를 갖게 되고, 이걸 확장해서 다른 범주의 정보를 만들 수도 있게 된다. 그리고 다른 사람이 나의 코드를 보더라도 이게 뭘까 라는 생각보다 일종의 라벨을 확인함으로써 쉽게 이 정보를 파악할 수 있을 것이다.

그럼 다시 돌아와서 비구조화 할당은 뭘까?. 흩어진 정보를 구조화 했으니 비구조화라고 하면 다시 흐트려뜨리는게 아닐까?.

const myName = myInform.name;
const myAge = myInform.age;

위와 같이 구조화된 정보를 각각 사용해야할 때 비구조화 했다고 표현할 수 있다. 즉, 구조화된 데이터를 분해하는 것을 비구조화(Destructuring)라고 한다. 그러면 비구조화 '할당'은 뭘까?

const { name, age } = myInfrom;

위와 같은 방법으로 하면 그 위에 방법보다 훨씬 간단하게 비구조화를 할 수 있고, 할당도 할 수 있다. 즉, name, age를 그대로 참조해서 쓰기만 하면 myInform.name, myInform.age 값을 쓸 수 있는 것이다.

이처럼 비구조화 할당은 ESNext에 추가된 문법으로 당연히 타입스크립트에서도 사용이 가능하다. 따라서 이를 한번 집고 넘어가고자 오랜만에 복습 차원에서 알아봤다.

추가로 비구조화 할당 관련 자주 쓰는 스킬적인 측면을 살펴보자.
1) rest parameter :

const { firstData, ...rest } = myInform; 

위와 같이 써주면 firstData에는 첫번째 정보인 name이 들어가고, rest에는

{
	age : 31,
    height : "177cm"
}

위와 같은 데이터가 들어간다. 비구조화 할당을 할 때 한번에 여러개를 할당하고 싶은 경우에 저런식으로 사용한다고 생각하면 된다.

2) Spread Syntax : 구조화 된 데이터를 전개 하도록 하는 문법이다. 예를 들어, 다시 위의 예시로 가보면 myInform 에 있는 정보에 더해서 나의 커리어 정보를 구조화해야하는 케이스가 있다고 생각해보자.

const myCareer = {
	...myInform,
    company : 'ncsoft',
    years : 2
}

위와 같이 해주면 결론적으로

console.log(myCareer);
// {
//   name : 'yongki',
//   age : 31,
//   height : '177cm',
//   company : 'ncsoft',
//   years : 2
// }

위와 같이 구조화돼있던 myInform 데이터가 전개돼 위와 같이 3개의 데이터가 추가된 새로운 변수가 된다.

3) swap : 파이썬을 할 때 굉장히 편하다고 생각했던 문법인데 JS에도 있었다

let a = 1, b = 2;
[a,b] = [b,a];
// a = 2, b= 1

내부 로직상으로 아마 주소값을 서로 변경해줘서 이렇게 되는게 아닐까 생각이든다. 추가로 코딩테스트를 볼 때도 이런것도 가능하다.

const arr = ['yongki', 'velog', 'kiyong', 'junhee', 'jae'];
// 5명의 사람이 있고, 1열로 앉은 상태이다. yongki를 kiyong이 있는 자리로 kiyong을 jae가 있는 자리로, jae를 yongki 자리로 바꿔라.

[arr[0], arr[2], arr[4]] = [arr[4], arr[0], arr[2]];

console.log(arr); 

간단하게 생각하면, 왼쪽에 있는 요소들을 하나의 변수라고 했을 때, 해당 변수에 대응되는(순서상으로) 오른쪽 값을 해당 변수에 넣어줌으로써 자리를 바뀐 것처럼 만드는 것이다(** 이렇게 세개를 한번에 하는식은 생각 못했는데 이것도 써먹을 곳이 있을 것 같다).

화살표 함수

: 자주 쓰는 화살표 함수도 ESNext에 나온 문법이다. 사실 큰 이점은 없고(물론, 화살표 함수와 function 키워드를 쓰는 함수는 this가 참조하는 값이 다르다는 차이가 있으니 주의 => 이 블로그를 참조하면 좋을 것 같다.) 코드를 간결하게 할 수 있다는 이점이 있다.

클래스 선언자

: 흔히 객체지향 프로그래밍이라고 하면 상속, 다형성, 캡슐화 이렇게 3개의 요소를 지원한다고 보면 되는데 예를 들어서, 다음과 같은 코드에 세가지 요소가 포함돼 있다고 보면 된다.

abstract class Animal {
	constructor (public name?: string, public age?: number) {}
    abstract say(): string
}

class Cat extends Animal {
	say() {return '야옹'}
}

class Dog extends Animal {
	say() {return '멍멍'}
}

위의 예시는 Animal이라는 부모 클래스를 상속받은 두개의 클래스가 있고, 두개의 클래스 내부에는 같은 부모 클래스를 받지만, say() 라는 함수를 실행했을 때 각각 다른 리턴값을 보인다(다형성). 마지막으로 이 클래스들은 객체의 세부 내용이 외부에 드러나지 않아 외부에서 데이터를 직접 접근하는 것을 방지함으로써 캡슐화를 이룬다. 이러한 클래스 선언자 또한 ES6에서 새로 나온 문법이었다.

모듈 기능

: 리액트 개발을 할 때 utils.js 등의 파일을 만들어놓고 거기에 각각의 모듈을 만들어놓고

export function checkNickname(nickname:string) {
	const response = checkValidation(nickname);
    return response;
}

위에처럼 자체적으로 만든 모듈을 선언 및 할당해서 export 해주면, 다른 컴포넌트 파일에서

import { checkNickname } from "./utils.js"

위와 같이 쓸 수 있었다. 이러한 모듈 export, import 기능도 ES6부터 나왔다.

생성기

: 생성기 & 반복기는 따로 포스팅해보기로 한다. 간단하게 생성기는 반복기를 제공하는 반복기 제공자이며 여기서 반복기를 생성할 때 쓰는 문법이 yield 이다. 따라서 반복기 제공자인 생성기 안에는 반복기를 제공할 수 있는 yield 키워드가 함께 쓰인다. 추가로, 생성기는 function 키워드에 별표(*)를 결합한 function* 형태로 쓰인다.

Promise와 async/await 구문

: 이것도 생성기와 마찬가지로 추후 다시 다루도록 한다.

profile
완벽함 보다는 최선의 결과를 위해 끊임없이 노력하는 개발자
post-custom-banner

0개의 댓글