포스트

TS 시작하기

TypeScript를 시작해보며 적는 글

TS 시작하기

🔴 TypeScript 란?

더 나은 개발 경험과 더 생산적인 개발을 원하는 JS 개발자 필요에 따라 JS를 사용할 때도 있으며, 프론트엔드 개발을 하고 싶을 때도 있음

Java / C# 같은 강형언어의 개발자인데 프론트엔드를 구현해야한다? 그러면서 타입 안정성이 없는 JS를 싫어한다면 TS를 바로 시작해

타입 안정성이 없다는건 버그도 많고 유지보수도 힘든점이 있기에, TS는 그 부분에서 JS를 완벽보완하는 수준의 언어이다.

🟠 TS와 컴파일러

TS는 C#, Java, Go, Rust와 같은 Strongly typed 프로그래밍 언어이다.
위와 같은 언어들을 떠올릴 때 컴파일러를 같이 떠올릴 수 있는데,
코드를 다 작성하고 나면 코드를 컴파일해서 0101 같은 컴퓨터 언어로 바꾸어준다.

이 컴파일러의 개념은, TS에서는 JS가 그 컴파일러의 역할을 하기 때문이다.

브라우저는 TS를 이해하지 않고 JS를 이해하기 때문에, TS만으로는 진행하는데에 어려움이 있음

🔴 TS를 하기 위한 Requirements

Node.JS 에서 제공하는 npm 을 통해 라이브러리를 이용하여 TS를 깔 수 있다.
( 또한, NodeJS는 TS와 JS를 둘 다 이해할 수 있어 사용하기에 용이하다. ) VSCode 는 여러 가지 플러그인을 제공하고, VSCode를 제작한 MS사가 TS를 만들었기 때문에, 여러 모로 연관성이 좋다고는 하지만 개인적으로는 아직 잘 모르겠다.

VSCode가 없다거나 개발 환경 세팅이 크게 필요하지 않다면,
온라인 편집기 같은 방법을 사용하는 것도 추천한다.

🔴 JS가 있는데 TS는 왜 존재하는가?

🟠 가장 큰 이유, 안정성

더 정확히는 타입의 안정성이다.
코드의 안정성 / 런타임에러가 줄고 / 버그가 줄어든다

여기서 타입 안정성이 없다는 게 무엇이냐면..

1
2
3
4
5
6
function divide(a, b) {
  return a / b
}

divide(2, 3)
// 0.666666..

이 함수에는 나누기를 위한 함수이며, 당연히 숫자를 넣으면 작동한다.

하지만 숫자 이외의 값을 넣으면 보통 에러를 일으켜 개발자에게 경고를 알려줌으로써 코드의 유효성을 다시생각하게끔 해주는게 JS에는 내장되어 있지 않다.

1
2
3
4
5
6
7
divide("XXXXX")
// NaN

/*
divide 함수는 두 개의 argument 값을 받는데, 
하나를 넣었고, 게다가 나누어지지 않는 String 값을 넣었는데도 에러를 내보내기는 커녕 NaN이라는 값을 내보낸다. 
*/

Java 나 C# 같은 언어들이었으면 값을 입력하는 과정에서 이미 경고를 해주었을 것이다.

그렇다고 JS가 아예 에러를 안내보내는건 아닌데, 그 에러는 런타임 에러이다.

🟠 에러 중에서도 최악인 런타임 에러

런타임 에러는 콘솔 안에서 일어나는 에러를 말한다.

1
2
3
4
const hyeun = { name : "hyeun" }

hyeun.hello()
// Uncaught TypeError 메시지

hyeun이라는 객체를 만들고, hello라는 함수를 실행시키지만 되지않는다
당연하지만, hello라는 함수를 만들지 않았기 때문이다.
여기서 볼건, TypeError 메시지가 실행시켰을 때 나왔다는 점이다.
다른 언어들이었으면 실행시키기도 전에 빨간줄이나 경고메시지를 띄웠을 거란 거다.

TS 를 사용한다면, 결과적으로 이 모든 문제가 해결된다.

아까 TS에서 JS로 컴파일을 하는 과정이 있음을 소개했는데,
그렇다면 TS는 JS에 비해 어떻게 코드의 안정성을 보장하는가?

결론부터 말하자면, TS는 변환된 JS안에서 에러를 잡아낸다.
이 과정은 보이지 않는다고 생각하는게, 만약 잘못된 TS코드를 작성하게 되면
TS에서 JS로 변환이 아예 안되기 때문이다. ( 에러코드가 있으면 변환하는 과정에서 잡는듯 )

반대로, JS가 정상적으로 실행된다면 TS코드도 맞다는 이야기이다.

🔴 TS의 Types

TS에는 Type 이라는 시스템이 있다. 다른 언어들에서도 일일히 변수나 함수들의 타입을 정해줘야하는 경우가 많다. ( Java 같은 명시적인 언어들 )

TS는 두가지 접근방식을 결합하였는데,

  1. 데이터와 변수의 타입을 명시적으로 정의하는 방법 ( Explicit Type )
    1
    
    let a : string = "x"
    

    이 경우, a 의 타입은 string 이기에 만약 string 이외의 값을 넣어주면 에러가 발생한다.

  2. JS처럼 변수만 생성하고 넘어가는 방법. ( 이 경우, TS에서 변수의 타입을 추론한다 ) ( Implicit Type )
    1
    
    let b = "Hello"
    

    b의 타입이 명시되어 있지 않기 때문에, TS 에서 추측하여 ( 들어간 값을 통해 )
    결과적으로 b의 타입은 string이 된다.

안정성 조금 더 어필 하는 차원에서 b의 코드를 JS로 보면

1
2
3
4
5
let b = "Hello"
b = 3

// 정상실행 ( b의 타입이 String -> number으로 바뀐다. )
// TS에서는 물론 에러가 뜬다. String이라 이미 추론한 상황에서 number타입을 넣으려 했기 때문이다. 

보통 상황에서는 명시적 표현은 최소한으로 쓰는 편이 좋은데, 왜냐하면 코드의 가독성이 좋아지기 때문이다. ( 한번 명시하면 변수의 타입을 바꾸는 건 흔하지 않으니까 )

🟠 Optional 타입

1
2
3
4
5
6
const player = {
  name: "devken65" 
}
// 만약, 
// player 객체가 여러개 있고, 
// 모든 player 객체는 name을 가지지만 몇몇은 age 라는 속성을 가진다 한다면?
1
2
3
4
5
6
7
8
const player : {
  name:string,
  age?:number
} = {
  name = "devken65"
}
// 구조는 player 객체에 타입을 명시하고, 그 다음 {} 에  실제 내용을 명시하는 구조이다. 
// 여기서 age는 선택적이어야하므로, 이름에 ? 를 붙여 있을수도 / 없을수도 한걸 알려준다. (optional parameter의 지정 방법)

🟠 Alias(별칭)

player 객체를 여러 개 만들어야 한다면, 똑같은 내용의 중복 코드가 발생하게 될텐데
중복 코드는 코드의 가독성을 떨어뜨리기에 Alias 를 이용하여 이 중복 코드를 줄여줄 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
type Player = {
  name:string,
  age?:number
}
// 이렇게 생성된 Alias를 이용해 객체를 만들게 되면
const devken65 : Player = {
  name:"devken65"
}
const devson21 : Player = {
  name:"devson21",
  age: 22
}
// 단순히 player 객체를 여러개 만들어 주는 것보다는 훨씬 나은 코드가 작성되었다 

TIP : Alias를 사용해서 이렇게 정돈도 가능하지만, 과사용은 자제하는편이 좋다.

1
2
3
4
5
6
type Name = string;
type Age = number;
type Player = {
  name:Name,
  age?:Age
}

🟡 Return 값의 타입을 지정하는 방법

지금까지는 객체에서의 타입명시를 보았고, 함수에서는 어떻게 하는지 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Player = {
  name:Name,
  age?:Age
}
function playerMaker(name:string) : Player {
  return {
    name // name : name 과 같다
    // 만약, argument의 이름과 return 에서의 객체가 같은 이름을 가진다면 저렇게 명시해줘도 에러는 발생하지 않는다.
  }
}

const devken65 = playerMaker("devken65")
devken65.age = 26
// Player 타입을 명시해주었기에, age값을 건드려도 문제가 발생하지 않는다. 

🟠 Readonly 속성을 추가하는법

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.