[TypeScript] TS 개요, Compile, 기본 Type

dosilv·2021년 6월 17일
2
post-thumbnail

💎 TypeScript?

💍 What is TS?

이름 그대로, JavaScript에 ✨Type✨을 부여한 JS 확장 언어!
JS의 특징 중 하나는 dynamically typed language라는 것인데, 프로그램이 동작할 때 data type이 결정되므로 runtime error가 발생하기 쉽다.
TS는 이러한 단점을 개선한 ✨statically typed language✨로, 코드를 짤 때부터 type을 결정하게 되어 있다. 변수 선언 시 타입을 지정해야 하고, 한번 결정되면 변경이 불가함! 그 덕분에 runtime error 대신 작동 전에 미리 compile error를 확인할 수 있어 작동 오류를 사전에 방지할 수 있다.

💍 Why TS?

🌊 안정성
타입 체킹을 통해 개발 과정에서 즉각적으로 에러 검사를 할 수 있기 때문에 안정적인 프로그래밍이 가능하다.

🌊 객체지향
객체지향프로그래밍(OOP, Object Oriented Programing)이란, 프로그램을 수많은 객체 단위로 나누고 이들이 상호작용하는 방식으로 프로그래밍하는 것을 말한다. 객체는 특정 기능을 수행하는 메서드와 변수의 묶음! 이를 통해 코드의 재사용성을 높이고 유지보수를 용이하게 만들 수 있다.
TS를 이용하면 class, interface, generic 등을 통해(아직 뭔진 모르겠지만...😞) 더욱 객체지향적인 프로그래밍이 가능하다고 한다!

🌊 호환성
TS로 짠 코드는 결국 JS 코드로 compile 과정을 거쳐서 사용된다. 그래서 JS가 동작하는 어떤 환경(client, server)에서도 쓰일 수 있음!
또한 컴파일러로는 TS 내장 tool 또는 barbell 등을 사용할 수 있는데, 컴파일링 시 target 선택을 통해 ES6, ES5 혹은 그 이하로도 자유롭게 버전을 조정할 수 있다. 그래서 브라우저 호환 문제로부터도 자유롭다.



💎 Compile

타입스크립트를 자바스크립트 파일로 컴파일하는 명령어를 알아보자!

💍 기본 compile 방법 👉 tsc [TS 파일명]

TS 코드를 JS 코드로 변환해 새 JS 파일을 생성해 줌

💍 tsc watch 모드 👉 tsc [TS 파일명] -w

watch 모드로 명령하면 TS 파일을 저장할 때마다 초기에 생성된 JS 파일에 변경사항을 반영해 줌!

💍 ts-node를 통한 간편 compile

ts-node는 TS 코드를 JS 코드로 변환하여 터미널에서 바로 실행해 주는 툴
설치 👉 npm install -g ts-node
실행 👉 ts-node main.ts



💎 기본 Type

아래에서는 모두 선언과 동시에 할당했지만, 변수명과 타입만 선언하고 나중에 값을 할당할 수도 있다.

💍 Number / String / Boolean

const/let 변수명: type = 할당할 값

지정한 type과 할당된 값의 type이 다르면 'Type [할당된 type] is not assignable to type [지정한 type]'이라는 에러가 뜬다.

const num: number = 0;
const str: string = 'Hello!';
const bool: boolean = true;

💍 Array

const/let 변수명: 요소로 들어갈 data type[] = 할당할 Array

혹은

const/let 변수명: Array<요소로 들어갈 data type> = 할당할 Array

let ages: number[] = [20, 30, 40];
let greetings: Array<String> = ['Hi', 'Hey', 'Hello']

첫 번째 방법에서 타입 앞에 readOnly를 붙여주면 배열의 불변성을 유지할 수 있다!

💍 Tuple

튜플은 요소의 타입개수 고정된 Array! 요소들의 타입이 동일할 필요는 없다.

const/let 변수명: [첫 번째 요소의 type, 두 번째 요소의 type, ..., n번째 요소의 type] = 할당할 Array

let tup: [string, number, boolean] = ['cookie', 5, true];

만약 지정된 타입과 다른 요소를 할당하거나, 지정되지 않은 인덱스에 접근하려고 하면 오류가 발생한다.

tup[2] = chocolate;
//Type 'string' is not assignable to type 'boolean'.

tup[1].toLowerCase();
//Property 'toLowerCase' does not exist on type 'number'.

tup[3] = false;
//Tuple type '[string, number, boolean]' of length '3' has no element at index '3'.

그러나 일관되지 않은 타입의 데이터들을 동일한 배열에 담고, key값 없이 index로만 접근하게 되면 어떤 데이터인지 확인이 어렵고 가독성이 떨어진다. 따라서 튜플보다는 classinterface, type alias로 대체해서 사용하기!

react에서 자주 쓰는 useState hooks도 사실 tuple을 구조분해할당해서 사용하는 형태이다.


💍 Object

primitive 타입(number, string, boolean)을 제외한 모든 형태의 object 할당 가능! 그러나 그렇게 되면 TS를 쓰는 의미가 퇴색되기 때문에 사용을 지양하자.


💍 Undefined / Null

let 변수명: (다른 type) | (undefined/null)

값이 정해져 있지 않거나(undefine) 없을 수도 있을 경우(null) '특정한 타입 혹은 undifined/null'이라고 가변적으로 선언할 수 있다.

let age: number | undefined;
age = undefined;
age = 20;

let name: string | null;
name = 'doeun';

💍 Unknown / Any

이 타입들로 지정하면 아무 type이나 할당이 가능하지만, 마찬가지로 TS의 목적에 부합하지 않기 때문에 사용은 지양... (타입이 없는 JS와 호환이 필요할 때나, 함수의 return 타입을 알 수 없을 때 예외적으로 사용)


💍 Void / Never

function 함수명(): void/never { }

둘 다 함수의 return 타입을 지정할 때 사용!
void: 함수의 return 값이 없을 경우 (:void 생략 가능)
never: 함수가 아무것도 return해서는 안 될 경우

function sayHi(): void {
  console.log('Hi!');
  return;
}

function throwError(message: string): never {
  //1. 에러를 던지거나
  throw new Error(message);
  //2. 무한 while loop인 경우
  while(true) { }
}

💍 Enum

Enumerated type(열거형)을 줄인 것으로, C, Java 등에서 많이 쓰이는 타입으로서 특정 상수들의 집합을 말한다.
숫자형 Enum문자형 Enum이 있는데, 선언 방식부터 살짝 차이가 있다.

🌊 숫자형

enum 변수명 {첫 번째 상수, 두 번째 상수, ..., n번째 상수}

enum nums {a, b, c}
  
console.log(nums[0]); //결과: a
console.log(nums.a); //결과: 0

위처럼 상수에 아무 것도 할당하지 않으면, 자동으로 0부터 숫자가 부여되어 인덱스처럼 접근할 수 있고, 반대로 상수로부터 숫자를 불러올 수도 있다.

만약 n번째 요소에 숫자를 할당하면, 해당 요소부터 숫자가 1씩 더해져서 할당된다. (다른 숫자가 수동으로 할당되지 않은 경우)

⚠ 그러나 어떤 변수에 숫자형 enum 값을 할당하면, 이후 그 변수에는 아무 숫자나 담을 수 있기 때문에 타입을 엄격히 보장할 수 없다.
Swift, Kotlin 등을 사용해 Union 타입이 없는 Android, IOS 프로그래밍을 하는 경우를 제외하고는 enum 대신 Union 타입을 이용하는 것이 더 안전함!

enum Nums {a, b = 5, c, d}
  
console.log(Nums.a); //결과: 0
console.log(Nums.c); //결과: 6
console.log(Nums[7]); //결과: d

🌊 문자형

enum 변수명 {첫 번째 상수 = '할당할 string', 두 번째 상수 = '할당할 string', ..., n번째 상수 = '할당할 string'}

하나의 상수에 문자열을 할당하게 되면, 나머지 상수들도 반드시 할당을 해 줘야 한다. 그렇지 않으면 Enum member must have initializer.라는 에러가 뜸.

enum Fruits {
  apple = '🍎',
  cherry = '🍒',
  lemon = '🍋',
  banana = '🍌',
}

console.log(Fruits.cherry) //결과: 🍒

그냥 Object와 비슷해 보이고, 실제로도 console.log(fruits)를 찍어 컴파일을 하면 JS문법상 일반 객체 형태로 변환되어 출력된다. 그러나 enum의 경우 객체와 달리 선언 후 변경이 불가능하고, 속성값으로 숫자 또는 문자열만 할당할 수 있음!



🔹 Reference 🔹

TypeScript: Documentation - The Basics
TS for OOP Programmers(en) · GitBook
Enums - TypeScript Deep Dive

profile
DevelOpErUN 성장일기🌈

0개의 댓글