TypeScript

타입스크립트 주요 문법 살펴보기

ziwookim 2022. 12. 5. 23:17

ESNext의 주요 문법 살펴보기

(1) 비구조화 할당(destructuring assignment)

ESNext는 '비구조화 할당(destructuring assignment)'이라고 하는 구문을 제공한다. 비구조화 할당은 객체와 배열에 적용할 수 있다. 다음 코드는 비구조화 할당을 적용한 예이다.

<비구조화 할당 예>

let person = {name: "Jane", age: 22}
let {name, age} = person // name = "jane", age = 22

let array = [1, 2, 3, 4]
let [haed, ...rest] = array // head = 1, rest = [2, 3, 4]

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

02행을 살펴보면 person 객체의 name과 age 속성을 비구조화 할당을 통해 쉽게 각 멤버를 얻는다. 05행은 배열에 비구조화 할당을 적용한 예이다. 배열에서 첫 번째 요소와 나머지행은 두 변수 a와 b의 값을 서로 교환(swap)하는 예이다.

 

(2) 화살표 함수(arrow function)

자바스크립트에서 함수를 선언할 때는 다음 코드의 01행처럼 function 키워드를 사용한다. 그런데 ESNext에서는 function 키워드 외에도 화살표(=>)로 함수를 선언할 수 있다. 02행에서는 화살표로 add2 함수를 만들었는데, 이처럼 화살표로 만든 함수를 '화살표 함수(arrow function)' 라고 한다.

<화살표 함수 예>

function add(a, b) {return a + b}
const add2 = (a, b) => a + b

코드는 될 수 있으면 간결하게 작성해야 읽기 좋다. 화살표 함수를 사용하면 function 키워드 방식보다 코드를 간결하게 만들 수 있다.

 

(3) 클래스 (class)

ESNext에서는 클래스라는 기능을 제공해 C++나 Java 언어에서 보던 객체지향 프로그래밍을 지원한다. 객체지향 프로그래밍은 프로그래밍 언어가 '캡슐화(encapsulation)'와 '상속('inheritance)', '다형성(polymorphism)'이라는 세 가지 요소를 지원한다. 다음 코드는 객체지향 프로그래밍의 세 가지 요소를 모두 보여준다.

<클래스 예>

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 '멍멍'}
}

let animals: Animal[] = [new Cat('야옹이', 2), new Dog('멍멍이', 3)]
let sounds = animals.map(a =>a.say()) // ["야옹", "멍멍"]

이 코드는 C++나 자바와 같은 언어로 객체지향 프로그래밍을 경험해 본 독자라면 낯설지 않을 것이다. ES5 자바스크립트로는 이러한 형태로 코드를 작성하지 못한다.

 

(4) 모듈 (module)

모듈을 사용하면 코드를 여러 개 파일로 분할해서 작성할 수 있다. 변수나 함수, 클래스 등에 export 키워드를 사용해 모듈로 만들면 다른 파일에서도 사용할 수 있다. 그리고 이렇게 만든 모듈을 가져오고 싶을 때는 import 키워드를 사용한다. 이처럼 ES5와 다르게 ESNext는 파일을 분할해서 구현할 수 있게 해주는 모듈 기능을 제공한다.

<모듈 예>

import * as fs from 'fs'
export function writeFile(filepath: string, content: any) {
	fs.writeFile(filePath, content, (err) => {
    	err && console.log('error', err)
    }
}

 

(5) 생성기 (generator)

타입스크립트는 물론 파이썬이나 PHP와 같은 몇몇 프로그래밍 언어는 yield 라는 특별한 키워드를 제공한다. yield문은 '반복자'를 의미하는 반복기(iterator)를 생성할 때 사용한다. 그런데 반복기는 독립적으로 존재하지 않고 반복기 제공자(iterable)를 통해 얻는다. 이처럼 yield문을 이용해 반복기를 만들어 내는 반복기 제공자를 '생성기(generator)'라고 부른다.

생성기는 function 키워드에 별표(*)를 결합한 function*과 yield 키워드를 이용해 만든다. 타입스크립트에서 yield는 반드시 function*으로 만들어진 함수 내부에서만 사용할 수 있다.

<생성기 예>

function* gen() {
	yield* [1, 2]
}
for(let value of gen()) { console.log(value) } // 1, 2

코드에서 01행의 function*을 생성기라고 한다. 이 생성기 덕분에 02행에서 yield라는 키워드를 사용할 수 있다. 코드에서 yield가 호출되면 프로그램 실행이 02행에서 일시 정지한 후 점프해서 04행을 실행한다. 그리고 04행 실행을 마치면 다시 02행을 실행하고, 이 과정을 02행의 배열 [1, 2]의 요소를 모두 순회할 때까지 반복한다. 이처럼 yield는 특별한 실행 흐름을 보여준다.

 

(6) Promise와 async/await 구문

ES5로 비동기 콜백 함수(asynchronous callback function)를 구현하려면 코드가 상당히 복잡하고 번거로워진다. 이 때문에 '콜백 지옥(callback hell)' 이라는 표현이 있을 정도다. Promise는 웹 브라우저와 노드제이에스(Node.js)에서 모두 제공하는 기본 타입으로 비동기 콜백 함수를 상대적으로 쉽게 구현할 목적으로 만들어졌다. ESNext는 C# 4.5 버전의 async/await 구문을 빌려서 여러 개의 Promise 호출을 결합한 좀 더 복잡한 형태의 코드를 간결하게 구현할 수 있게 한다.

<Promise와 async/await 예>

async function get() {
	let values = []
    values.push(await Promise.resolve(1))
    values.push(await Promise.resolve(2))
    values.push(await Promise.resolve(3))
    return values
}
get().then(values => console.log(values)) // [1, 2, 3]

코드에서 01행의 함수는 async 함수 수정자(function modifier)를 사용한다. async를 사용한 함수는 본문에서 await 키워드를 사용할 수 있다. await는 Promise 객체를 해소(resolve)해 준다. 따라서 아래 get 함수는 [1, 2, 3] 값을 Promise 형태로 반환한다. get이 반환한 Promise 객체는 then 메서드를 호출해 실제 값을 얻을 수 있다.

 

타입스크립트 고유의 문법 살펴보기

(1) 타입 주석과 타입 추론

다음 코드에서 01행의 변수 n 뒤에는 콜론(:)과 타입 이름이 있다. 이것을 '타입 주석(type annotation)'이라고 한다.

<타입 주석과 타입 추론 예>

let n: number = 1
let m = 2

그런데 타입스크립트는 02행처럼 타입 부분을 생량할 수도 있습니다. 타입스크립트는 변수의 타입 부분이 생략되면 대입 연산자(=)의 오른쪽 값을 분석해 왼쪽 변수의 타입을 결정한다. 이를 '타입 추론(type inference)'이라고 한다. 타입스크립트의 타입 추론 기능은 자바스크립트 소스코드와 호환성을 보장하는 데 큰 역할을 한다. 타입 추론 덕분에 자바스크립트로 작성된 '.js' 파일을 확장자만 '.ts'로 바꾸면 타입스크립트 환경에서도 바로 동작한다.

 

(2) 인터페이스 (interface)

다음 코드의 인터페이스 구문은 타입이 있는 언어를 경험해 본 독자라면 낯설지 않을 것이다.

<인터페이스 예>

interface Person {
	name: string
    age?: number
}

let person: Person = { name: "Jane" }

 

(3) 튜플 (tuple)

파이썬과 같은 몇몇 프로그래밍 언어에는 튜플(tuple)이라는 타입이 있다. 튜플을 물리적으로는 배열과 같지만, 배열에 저장되는 아이템의 데이터 타입이 모두 같으면 배열, 다르면 튜플이다.

<배열과 튜플>

let numberArray: number[ ] = [1, 2, 3] // 배열
let tuple: [boolean, number, string] = [true, 1, 'Ok'] // 튜플

 

(4) 제네릭 타입 (generic type)

제네릭 타입은 다양한 타입을 한꺼번에 취급할 수 있게 해준다. 다음 코드에서 Container 클래스는 value 속성을 포함한다. 이 클래스는 Container<number>, Container<string>, Container<number[]>, Container<boolean>처럼 여러 가지 타입을 대상으로 동작할 수 있는데 이를 '제네릭 타입(generic type)'이라고 한다.

<제네릭 타입 예>

class Container<T> {
	constructor(public value: T) { }
}
let numberContainer: Container<number> = new Container<number>(1)
let stringContainer: Container<string> = new Container<string>('Hello world')

 

(5) 대수 타입 (algebraic data type)

ADT란, 추상 데이터 타입(abstract data type)을 의미하기도 하지만 대수 타입(algebraic data type)이라는 의미로도 사용된다. 대수 타입이란, 다른 자료형의 값을 가지는 자료형을 의미한다. 대수 타입에는 크게 합집합 타입(union 또는 sum type)과 교집합 타입(intersetion 또는 product type) 두 가지가 있다. 합집합 타입은 '|' 기호를 교집합 타입은 '&' 기호를 사용해 다음 코드처럼 여러 타입을 결합해서 만들 수 있다.

<대수 타입 예>

type NumberOrString = number | string // 합집합 타입 예
type AnimalAndPerson = Animal & Person // 교집합 타입 예

 

 

출처: <Do it! 타입스크립트 프로그래밍> 이지스퍼블리싱

'TypeScript' 카테고리의 다른 글

타입스크립트란 무엇인가?  (0) 2022.12.05