타입스크립트는 마이크로소프트가 개발하고 유지하고 있는 오픈소스 언어
- 표준 자바스크립트 (ECMAScript)
- ESNext
- 타입스크립트 (TypeScript)
ESNext는 ECMAScript의 모든 문법을 포함한다.
Typescript는 ESNext의 모든 문법을 포함한다.
현대의 소프트웨어는 상당히 복잡하고, 보통 여러 사람이 협력해 개발을 한다.
이런 상황에서 코드를 작성하는 쪽과 사용하는 쪽의 커뮤니케이션이 중요하게 여겨진다.
function makePerson(name, age) {}
위와 같은 함수를 A라는 개발자가 작성하고 B라는 개발자가 아래와 같이 사용했다.
makePerson(32, "Jack");
다른 개발자가 위와 같은 코드를 실행했을때 오류가 발생한다면 원인을 찾기 힘들다.
function makePerson(name: string, age: number) {}
위와 같이 타입 기능을 사용해 구현했다면 이런 문제가 발생하지 않았을 것이다.
타입스크립트 컴파일러는 오류를 친절하게 알려줘 코드를 더 수월하게 작성할 수 있다.
ESNext 코드는 바벨이라는 트랜스파일러를 거쳐 ECMAScript로 변환된다.
바벨과 유사하게 타입스크립트는 TSC라는 트랜스파일러로 ECMAScript로 변환된다.
트랜스파일러
어떤 언어로 작성된 소스코드를 또 다른 언어로 된 소스 코드로 바꿔주는 프로그램을 말한다.
텍스트로된 소스코드를 바이너리 코드로 바꿔주는 컴파일러와 구분하기 위해 생긴 용어다.
타입스크립트는 ESNext 문법을 대부분 지원한다.
타입스크립트를 다루기 위해서 ESNext 문법을 알아야한다.
추가적으로 타입스크립트의 고유한 문법도 존재한다.
ESNext는 비구조화 할당(Destructuring Assignment) 구문을 제공한다.
비구조화 할당은 객체({}
)와 배열([]
)에 적용할 수 있다.
- 비구조화 할당을 통해 객체의 속성을 얻는 예제
let person = { name: "Jane", age: 23 };
let { name, age } = person;
console.log("name :", name); // name : Jane
console.log("age :", age); // age : 23
- 비구조화 할당을 통해 배열을 분리하는 예제
let array = [1, 2, 3, 4];
let [head, ...rest] = array;
console.log("head :", head); // head : 1
console.log("rest :", rest); // [2, 3, 4]
- 비구조화 할당을 통해 값을 교환하는 예제
let a = 1,
b = 2;
[a, b] = [b, a];
console.log("a :", a); // a : 2
console.log("b: ", b); // b : 1
자바스크립트에서 함수를 선언할 때는 function
키워드를 사용한다.
ESNext
에서는 function
키워드 외에도 =>
로 함수를 선언할 수 있다.
=>
를 이용해 만든 함수를 화살표 함수(Arrow Function)이라고 한다.
function
키워드를 이용해 선언한 함수
function add(a, b) {
return a + b;
}
console.log(add(1, 2)); // 3
=>
를 이용해 선언한 화살표 함수
const add = (a, b) => a + b;
console.log(add(1, 2)); // 3
화살표 함수를 사용하면 function
을 이용한 방식보다 간결하게 코드 작성이 가능하다.
ESNext에서는 클래스 기능을 제공해 객체 지향 프로그래밍을 지원한다.
객체 지향 프로그래밍은 캡슐화, 상속, 다형성을 지원한다.
- 클래스를 이용해 객체 지향 프로그래밍의 요소를 보여주는 예시
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()); // ["야옹", "멍멍"]
모듈을 사용하면 코드를 여러 파일로 나누어 작성할 수 있다.
변수나 함수, 클래스등에 export
를 사용해 모듈로 만들면 다른 파일에서 사용 가능하다.
이렇게 만든 모듈을 가져와 사용하고 싶으면 import
키워드를 사용한다.
- 모듈생성 및 사용 예시
import * as fs from "fs";
export function writeFile(filepath: string, content: any) {}
yield
문은 반복기(iterator)를 생성할 때 사용한다.
yield
문을 이용해 반복기를 만들어 내는 제공자를 생성기(Generator)라고 부른다.
생성기는 function
키워드에 *
를 결합한 function*
과 yield
를 이용해 만든다.
타입스크립트에서 yield
는 만드시 function*
으로 만들어진 함수 내부에서만 사용가능하다.
function*
과yield
를 이용해 만드는 생성기 예시
function* gen() {
yield* [1, 2];
}
for (let value of gen()) {
console.log(value); // 1, 2
}
위의 코드에서 function*
을 생성기라고 한다.
위의 코드에서 yield
가 실행되면 정지한 후 for
문으로 점프해 실행된다.
for
문의 실행을 마치면 다시 yield
로 돌아가고 배열의 모든 요소를 순회하면 종료된다.
ECMAScript로 비동기 콜백 함수를 구현하려면 코드가 복잡해진다.
Promise
는 비동기 콜백 함수를 상대적으로 쉽게 구현할 목적으로 만들어졌다.
ESNext는 async
, await
구문으로 여러 Promise
의 호출을 간결하게 구현하도록 한다.
- Prmoise와 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]
async
키워드를 사용한 함수 내부에서는 await
키워드를 사용할 수 있다.
await
은 Promise
를 resolve
해주어 get
함수는 [1, 2, 3]
을 Promise
형태로 반환한다.
Promise
객체는 then
메서드를 호출해 실제 값을 얻을 수 있다.
아래의 예시에서 변수 n
뒤에 :
과 타입 이름을 작성한 것을 타입 주석이라고 한다.
- 타입 주석 예시
let n: numvber = 1;
아래와 같이 타입 부분을 생략할 수도 있으며 이를 타입 추론이라고 한다.
타입이 생략되면 =
연산자의 오른쪽 값을 분석해 타입을 결정한다.
- 타입 추론 예시
let m = 2;
타입 추론기능은 자바스크립트 코드와의 호환성을 보장하는 데 큰 역할을 한다.
타입 추론 덕분에 .js
파일을 .ts
로 바꾸면 타입스크립트 환경에서도 동작한다.
인터페이스는 객체의 속성 혹은 메소드에 관한 정보를 갖는다.
Person
인터페이스는 string
타입의 name
과 number
타입의 age
를 갖는다.
?
가 붙은 속성은 객체에 존재하지 않아도 person
과 같이 오류가 발생하지 않는다.
- 인터페이스 예시
interface Person {
name: string;
age?: number;
}
let person: Person = { name: "Jane" };
튜플은 물리적으로 배열과 동일하다.
배열은 저장되는 아이템의 데이터 타입이 모두 같지만 튜플은 그러지 않아도 된다.
- 튜플 예시
let numberArray: number[] = [1, 2, 3];
let tuple: [boolean, number, string] = [true, 1, "Ok"];
제네릭 타입은 다양한 타입을 한번에 취급할 수 있게 해준다.
아래의 예시에서 Container
클래스는 value
속성을 갖는다.
Container<number>
, Container<string>
같이 여러 타입을 대상으로 동작할 수 있다.
- 제네릭 타입 예시
class Container<T> {
constructor(public value: T) {}
}
let numberContainer: Container<number> = new Container<number>(1);
let stringContainer: Container<string> = new Container<string>("Hello World");
ADT는 추상 데이터 타입을 의미하기도 하지만 대수 타입이라는 의미로도 사용된다.
대수 타입은 다린 자료형의 값을 갖는 자료형을 의미한다.
크게는 &
를 사용한 합집합 타입과 |
를 사용한 교집합 타입이 존재한다.
- 대수 타입 예시
type NumberOrString = number | string;
type AnimalAndPerson = Animal & Person;
- 패키지 매니저 (
Scoop
,brew
) - 텍스트 에디터 (
VSCode
,Atom
, etc...) git
node.js
- 웹 브라우저 (
Chrome
,Whale
,Safari
, etc...)
Typescript는 node.js
환경에서만 동작한다.
따라서 node.js
의 패키지 관리자인 npm
을 이용해 설치한다.
> npm i -g typescript
> tsc -v
hello.ts
파일을 생성한 후 아래의 코드를 작성한 후 저장한다.
아래의 명령어를 터미널에서 실행한다.
작성한 Typescript가 Javascript로 트랜스파일되어 나온다.
트랜스파일된 Javascript는 node
명령어로 실행시킬 수 있다.
tsc
는 Typescript를 Javascript로 변환만한다.
변환과 동시에 실행하기 위해서는 ts-node
패키지를 설치하면 된다.
> npm i -g ts-node
ts-node
명령어로 컴파일과 실행을 동시에 할 수 있다.