※해당 글은 "NestJS로 배우는 백엔드 프로그래밍"(한용재 저)를 토대로 공부한 것을 정리한 것임을 밝힙니다.
타입스크립트
타입스크립트는 마이크로소프트에서 개발한 언어이다. 자바스크립트 코드에 타입 시스템을 도입하여 런타임에 에러가 발생할 가능성이 있는 코드를 정적 분석으로 찾아준다. 타입스크립트는 자바스크립트에 구문을 추가하여 만들어졌다. tsc 명령으로 컴파일하여 자바스크립트 코드로 변환가능하다. 컴파일 후 생성된 자바스크립트는 타입이 없다. 자바스크립트에 원래 타입이 없기 때문이다. 타입스크립트가 제공하는 타입 추론은 타입오류로 인해 런타임에 발생하는 오류를 컴파일 타임에 잡아준다. 이는 대규모 프로젝트에서 유용하다.
변수 선언
타입스크립트에서 변수를 선언하는 방식은 다음과 같다.
[선언키워드] [변수명]: [타입]
선언키워드: const, let 또는 var로 선언한다.
1. const: const를 이용하여 상수를 선언할 수 있다. 블록 단위(block-scoped) 변수로, 블록 내에서만 유효하다.
2. let: let을 이용하여 변수를 선언할 수 있다. 블록 단위(block-scoped) 변수로, 블록 내에서만 유효하다.
3. var: var로 선언된 변수는 호이스팅(hoisting)이 발생하여, 변수가 선언되기 전에도 참조할 수 있다. 이를 해결하기 위해 let과 const가 나왔다.
var로 선언한 변수는 같은 이름으로 다시 선언할 수 있지만, let으로 선언한 변수는 같은 이름으로 다시 선언할 수 없다.
var i = 0;
var i = 1;
var i = 2;
console.log(i);//2
let j = 0;
let j = 1;//Error: Identifier 'j' has already been declared
Typescript에서 지원하는 타입
타입스크립트는 자바스크립트가 가지고 있는 자료형을 모두 포함한다. 자바스크립트의 타입은 기본타입(Primitive value)과 객체형(Object), 함수형(Function)이 있다.
typeof | 설명 | 할당 가능한 값 |
boolean | 참, 거짓을 나타내는 논리값 | true, false |
null | "유효하지 않음"을 나타낸다 | null |
undefined | 값이 존재하지 않음. 즉, 변수 선언 후 "값이 할당되지 않음"을 나타낸다 | undefined |
number | 배정밀도 64비트 형식 IEEE 754의 값 | -(2^53 -1) 와 2^53 -1 사이의 정수와 실수 +Infinity, Infinity NaN (Not a Number) |
bigint | Number의 범위를 넘어서는 정수를 안전하게 저장하고 연산할 수 있게 해 준다 | ex) const x = 2n ** 53n; 정수 끝에 n을 추가한다 |
string | 문자열. 변경 불가능(immutable)하다 | 홑따옴표 또는 쌍따옴표로 둘러싸인 문자열 ex) 'hello', "world" |
symbol | 유일하고 변경 불가능한 (immutable) 기본값(primitive value) 객체 속성의 키로 사용할 수 있다 |
객체 타입
객체 타입은 속성(Property, 프로퍼티)을 가지고 있는 데이터 컬렉션이다.
const user1 = {
name: 'Tom',
age: 20,
hobby: ['Coding', 'Game'],
}
자바스크립트에는 개발할 때 유용한 내장 객체들이 있다.
- Date: 1970년 1월 1일 UTC 자정과의 시간 차이를 밀리초 단위로 나타낸 것으로 시간을 다룰 때 사용한다.
- 배열(Array): 정수를 키로 가지는 일련의 값을 가진 객체이다. 코드로 표현할 때는 대괄호([])로 표현한다.
- 키를 가진 컬렉션: Map, WeakMap은 키와 값을 가지는 객체 타입이고, Set과 WeakSet은 유일값들로 이루어진 컬렉션 객체 타입이다.
- JSON: JSON(JavaScript Object Notation)은 자바스크립트에서 파생된 경량 데이터 교환 형식이지만 많은 프로그래밍 언어에서 사용된다. JSON은 범용 데이터 구조를 구축한다.
함수(Function) 타입
자바스크립트는 함수를 변수에 할당하거나 다른 함수의 인자로 전달할 수 있고, 함수의 결과로 반환할 수도 있다.
any / unknown / never
타입스크립트에는 특수한 타입이 있다.
●any: 자바스크립트와 같이 어떠한 타입의 값도 받을 수 있는 타입이다. any 타입의 객체 역시 어떤 타입의 변수에도 할당이 가능하다. 이 특성 때문에 런타임에 오류를 일으킬 가능성이 있다.
●unknown: any타입과 마찬가지로 어떤 타입도 할당 가능하지만 다른 변수에 할당 또는 사용할 때 타입을 강제하도록 하여 any가 일으키는 오류를 줄여 준다.
●never: 변수에는 어떤 값도 할당할 수 없다. 함수의 리턴 타입으로 지정하면 함수가 어떤 값도 반환하지 않는다는 것을 뜻하고, 다음과 같이 특정 타입의 값을 할당받지 못하도록 하는 데 사용할 수도 있다. <T>는 제네릭 타입인데 이후에 설명한다.
type NonString<T> = T extends string ? never : T;
타입 정의하기
타입 스크립트는 타입을 정의해서 사용할 수 있다. 기본타입과 같은 타입을 정의한다는 뜻은 아니고, 위에서 설명한 타입들을 조합하여 타입에 이름을 붙여 사용한다.
다음 코드를 vscode에 입력하고 마우스를 user 변수 위로 가져가 보면
const user = {
name: 'Dexter',
age: 21,
}
추론된 타입이 다음과 같이 표시된다.
const user: {
name: string;
age: number;
}
변수에 객체를 바로 할당하지 않고 interface로 정의할 수 있다. 인터페이스를 이용하여 User 타입을 선언하는 것이다.
interface User {
name: string;
age: number;
}
const user: User = {
name: 'Dexter',
age: 21,
}
//에러 발생
const test: User = {
name: 3,
age: 4,
}
interface는 class로 선언할 수도 있다.
class User {
constructor(name: string, age: number) { }
}
const user: User = new User('Dexter', 21);
type 키워드로 새로운 타입을 만들 수 있다.
type MyUser = User;
MyUser 타입은 기존 User 타입을 그대로 사용하지만 내가 사용하는 도메인에 맞는 이름으로 바꾼 것이다.
타입 구성하기
자바스크립트는 변수에 어떠한 타입의 값도 할당할 수 있다. 덕 타이핑이라 부른다. 타입스크립트도 여러 타입의 값을 할당할 수 있다. 여러 타입을 조합한 새로운 타입을 가지는 것이다.
유니언 (Union) 타입
유니언 타입이 위에서 설명했던 여러 타입을 조합한 타입이다. 다음 코드에서 getLength 함수의 인자인 obj는 string 또는 string 배열 타입을 가질 수 있다.
function getLength(obj: string | string[]) {
return obj.length;
}
유니언 타입을 활용하면 변수가 가질 수 있는 값을 제한할 수도 있다.
type Status = "Ready" | "Waiting";
제네릭(Generic) 타입
Java나 C#에서의 제네릭과 유사한 기능을 한다. 어떠한 타입이든 정의될 수 있지만 호출되는 시점에 타입이 결정된다. 만약 다음과 같이 인자를 그대로 리턴하는 함수가 있다고 하면
function identity(arg: any): any {
return arg;
}
이 함수의 반환값은 any로 되어 있기 때문에 arg에 'test'를 인자로 전달할 경우 전달한 인자의 string 타입이 반환할 때 any가 되어 버린다. 반면 다음과 같이 제네릭 타입을 사용하게 되면 리턴되는 값의 타입은 함수를 호출하는 시점의 인자로 넣은 타입으로 결정되도록 할 수 있다.
function identity<T>(arg: T): T {
return arg;
}