[TS] 타입스크립트란? 사용하는 이유, 사용 방법

Sungho Kim·2022년 12월 19일
0

JavaScript

목록 보기
5/5
post-thumbnail

시작에 앞서,

포트폴리오 리뷰를 받았는데 타입스크립트에 대한 내용이 없다는 피드백을 받았다. 타입스크립트를 적용해보기 전에는 굳이 자바스크립트만으로 프로젝트를 진행하는게 문제가 없는데 타입스크립트를 꼭 써야하나? 라는 의문을 품었는데, 타입스크립트를 써보니 장점이 명확하다 생각해서 더 깊이 공부해보고 정리하기 위해 포스팅을 작성했다.

typescript란?

타입스크립트는 자바스크립트에 타입을 부여한 언어입니다. 자바스크립트의 확장된 언어라고 볼 수 있습니다. 타입스크립트는 자바스크립트와 달리 브라우저에서 실행하려면 파일을 한번 변환해주어야 합니다. 이 변환 과정을 우리는 컴파일(complile) 이라고 부릅니다

인터넷에 나와있는 장점 말고 내가 느낀 장점을 말해보자면
1. 프로그래밍을 하는 방식을 바꿔준다
2. 오류를 잡아준다
3. 개발 생산성 향상

여러가지 장점 중 가장 큰 장점은 프로그래밍을 하는 방식을 바꿔주는 툴이라고 생각한다.

1. 프로그래밍 하는 방식을 바꿔준다

자바스크립트로 코딩 방식

추측 -> 실행 -> 결과 -> 디버깅

  • 기존에는 어떤 기능을 구현할때 여기에 이런 정보가 들어올것이야(추측)
  • 이 정보를 기반으로 이건 h1 tag에, 이건 img태그에 넣어주면 좋겠군(실행)
  • 잘 작동하는지 볼까? (결과)
  • 에러가 났네 (디버깅)

타입스크립트로 코딩하는 방식

선언 -> 실행 -> 결과 -> 디버깅

  • 이런 데이터가 들어와야해 (선언)
  • 각각의 데이터를 맞는 태그에 넣으면 되겠네 (실행)
  • 잘 작동하는지 볼까? (결과)
  • 에러가 났네 (디버깅)

선언과 추측의 차이

그림으로 비유하면, 미리 구도와 비율을 어느정도 밑그림을 그려놓고 그림을 그리는 것과 그런 계산없이 무작정 그리는 것의 차이라고 생각한다. 타입을 정의하고 생각후에 코딩을 함으로써, string, array 등의 프로토타입 메서드들을 오류 없이 사용할 수 있고, 컴포넌트를 넣어서 컴포넌트를 넣는 HOC 컴포넌트를 만들때 필요한 prameter을 미리 생각함으로써 데이터의 과소적합을 피할 수 있다. 타입스크립트를 사용함으로서, 미리 기획하고 선언함으로서 효율성과 정확성을 증가시킬 수 있다는게 나에겐 가장 큰 장점으로 다가왔다.

2. 오류를 사전에 잡아준다.

자동차를 만든다고 했을때, 각 부분들이 모여서 자동차가 만들어질것이다. 마지막 공장에서 자동차 조립을 한다고 했을때, 자동차 조립 공장에서 바퀴 공기압에 문제가 없는지, 핸들의 문제가 없는지, 기어시프트에 문제가 없는지 등을 모든 부품을 조립 후에 검사한다고 했을때, 문제의 여부를 파악하기 위해선 아마 엄청난 시간이 걸릴것이다.
그럼 실제 자동차 공장에선 어떤식으로 오류를 잡을까? 각 공정마다 QA가 존재하고, quality를 충족하지 못한 제품들은 다음 공정으로 갈 수 없다. 자바스크립트에선 타입스크립트가 그 역할을 하고 있는데, 파라미터가 제대로 왔는지, 그 파라미터는 어떤 형식이여야 하는지, 넘겨질 파라미터와 보낼 파라미터의 타입이 일치하는지 등의 작업을 해준다.

3. 개발 생산성 향상

타입스크립트를 사용함으로서 개발 생산성이 향상된다. 물론 초기 셋팅을 하고, 해당 문법을 공부하는데 시간이 들지만, type을 선언함으로서 해당 타입이 갖고 있는 메서드를 쉽게 사용할 수 있다는 장점이 있다.
예를들어 타입을 정의하고, return되는게 array가 확실하다면, 타입스크립트는 array에 메서드인 map, set등의 기능을 리턴된 값에 바로 사용 가능하게 만들어준다. 자바스크립트로 작성할 경우, 이게 array인지 확인 과정을 넣고 array인 경우 해야한다는 조건문을 넣거나 하는 과정이 생략되다보니 적게는 10초, 많게는 몇분씩이 매 함수마다 아껴진다는 것은 개발 생산성에 크게 기여한다고 생각한다.

Typescript Fundamental

기본타입

  • Boolean
let isLoggedIn: boolean = true;
  • Number
let num: number = 10; 
  • String
let str: string = "hi" ;
  • Array
let numberArr: number[] = [1,2,3]; // 타입
let numberArr: Array<number> = [1,2,3]; //제네릭
let stringArr: string[] = ["hi","bye","see you"]; //타입
let stringArr: Array<string> = ["hi","bye","see you"]; //제네릭
  • Tuple
    튜플은 배열의 길이가 고정되고 각 요소의 타입이 지정되어 있는 배열 형식을 의미한다.
let arr: [string, number] = ["hi", 10];
  • Enum
    이넘은 C, Java와 같은 다른 언어에서 흔하게 쓰이는 타입으로, 특정 값(상수)들의 집합을 의미한다.
enum Avengers {Capt, IronMan, Thor};
let hero: Avengers = Avengers.Capt;
  • Any
let str: any = "hi";
let num: any = 10;
let arr: any = ["a", 2, true];
  • Void
    변수에는 undefined와 null만 할당하고, 함수에는 반환 값을 설정할 수 없는 타입이다.
let unuseful: void = undefined;
function notuse(): void {
  console.log('sth');
}

함수타입

함수의 기본적인 타입 선언하는 방법

가장 기본적인 함수부터 알아보자

function add(a, b) {
  return a + b;
}
function add(a: number, b:number): number {
  return a + b;
}

const add = (a:number, b:number) => a+b;

이렇게 들어오는 파라미터에 직접 타입을 하는 방법이 있다.

타입을 미리 선언하고 함수를 만드는 방법

type Add =(a:number, b:number) => number;

const add:Add = (a, b) => a+b;

하지만 이런 방법보다 add의 모양이 어떻게 될지 미리 타입을 지정하는 방법이 개인적으로는 더 좋다고 생각하는데, 앞서 언급한거처럼 미리 이 함수를 먼저 설계하고, 선언을 함으로서 함수의 설계를 할수 있다는 측면에서 미리 타입핑 하는 방법을 개인적으로 선호한다.

인터페이스

인터페이스는 상호 간에 정의한 약속 혹은 규칙을 의미한다. 타입과 가장 큰 차이점은 타입은 함수, 객체 어디든 사용 가능하지만, 인터페이스는 객체에 특화되어 있는 타입이다.

interface CraftBeer {
  name: string;
  hop?: number;  
}

let myBeer = {
  name: 'Saporo'
};
function brewBeer(beer: CraftBeer) {
  console.log(beer.name); 
}
brewBeer(myBeer); // Saporo

이런식으로 interface로 정의를 한 후에 파라미터에 객체 속성을 부여해서 사용이 가능하고, 클래스타입으로

interface CraftBeer {
  beerName: string;
  nameBeer(beer: string): void;
}

class myBeer implements CraftBeer {
  beerName: string = 'Baby Guinness';
  nameBeer(b: string) {
    this.beerName = b;
  }
  constructor() {}
}

이런식으로 클래스 객체를 만들때 유용하게 사용할 수 있다.

제네릭

제네릭이란 타입을 마치 함수의 파라미터처럼 사용할 수 있다. 특히 타입을 미리 정의하지 않아도 타입스크립트가 알아서 타입을 배정해주기 때문에 어떤 타입이 들어갈지 모르는 타입을 정의하기에 좋다.

예를들어

type SuperPrint = {
	(arr: number[]):void
}

const superPrint: SuperPrint = (arr) =>{
	arr.forEach(i => console.log((i))
}

superPrint([1,2,3,4]) /// 1,2,3,4
superPrint(["hi","buy"]) /// type "string" is not assignable to type "number"

이런경우 숫자나 문자, bool등의 타입중 어떤 타입의 정보가 들어올지 모르는 경우에 사용할 수 있다.

type SuperPrint = {
	<T>(arr: T[]):void
}

const superPrint: SuperPrint = (arr) =>{
	arr.forEach(i => console.log((i))
}

const a = superPrint([1,2,3,4]) /// 1,2,3,4
const b = superPrint(["hi","buy"]) /// hi,buy

any와 generic의 차이점은
제네릭을 사용한 경우 a는 number type으로 추론이 되서 a.length가 가능하지만, any를 사용한 경우, a의 타입이 지정이 되지 않았기 때문에 원시타입에 지정되어 있는 메서드를 사용할 수 없다는점이다.

클래스

typescipt에서는 javascript에서는 지원하지 않는 private, public, protected 라는 개념이 존재한다.

자바스크립트를 제외하고 c, python, c# 등등 다른 언어에는 있는 기능이지만 자바스크립트에는 존재하지 않는데, 이걸 타입스크립트를 통해 구현이 가능하고, 이러한 기능덕에 안정성이 향상된다.

pivate : class 스콥 내에서만 사용 가능(상속받은 클래스에선 사용 불가)
public : class를 통해 만들어진 모든 객체에서 사용 가능
public : class를 상속받은 class 객체에서만 사용 가능하다.

class Player {
  constructor(
  	private firstName: string,
    private lastName: string,
    public nickname: string
  ){}
}

const sungho = new Player("sungho","kim","otter");

console.log(sungho.firstname); // property 'firstName' is private and only accessible within class "player"
console.log(sungho.nickname); // otter

Absctract Class

추상 클래스는 다른 클래스에서 상속 받을 수 있는 클래스다. 하지만 이 클래스로 직접 사용은 불가능하다.

absctract class User {
  constructor(
  	private firstName: string,
    private lastName: string,
    public nickname: string
  ){}
  public getFullName(){
  	return `${this.firstName} ${this.lastName}`
  }
}

const sungho = new User("sungho","kim","otter");// cannot create an instance of an abstract class

class Player extends User {};

const sungho = new User("sungho","kim","otter");
console.log(sungho.nickname); // otter

const sungho.getFullName() // sunghoKim

마무리,

개발에 있어서 생산성을 향상시키는 방법이 무엇일까에 대한 고민을 끊임없이 하는 편이다. 개발 직군에 있으면서 가장 좋았던 점이라고 하면, 어떤 비효율성을 발견하게 될때 끊임없이 고민함으로서 더 나은 해결책을 찾을 수 있었던것 같다. 비개발직군, 특히 사람을 상대하거나 사람이 해야하는 일일수록, 변수가 많이 일어나는데 그럴땐 비효율성을 발견하더라도 그걸 상황적으로 개선할 수 없을때가 많다고 생각한다.
개선이 가능하지만 할수 없는 것과, 개선이 불가능한 것은 큰 차이가 있다. 다행히 개발 직군에서는 대부분의 경우 개선 가능한 선택지가 있어서 좋다. 타입스크립트는 자바스크립트를 더 효율적이게 사용할 수 있게 도와주는 좋은 툴이니 사용을 안할 이유가 없다고 생각한다.
끝으로 생활코딩에서 포스팅된 글을 감명깊게 읽었는데 한번 읽어보면 좋을꺼 같아서 가져와봤다.


수동으로 작업하면 5분 
코딩으로 자동화하는데 20시간
이 걸리는 일을 방금 '거의' 끝냈습니다.
내일 마저 할 생각입니다. 


수동으로 5분 걸리는 일을 
자동으로 구현하는데 20시간이 걸렸다니 
가성비가 형편 없죠? 
자동화를 했더니 240배가 느려졌습니다.


그런데 만약 이 일을 3번 한다면 
여전히 80배 느립니다. 


그런데 만약 이 일을 일주일 동안 매일 3번씩 했다면
여전히 11배 느립니다.


그런데 만약 이 일을 일년동안 빠짐없이 해야 한다면 
4.5배 빠른 샘입니다. 


그런데 만약 이 일을 십년동안 한다면 
46배 빠른 샘입니다.


그런데 만약 이 작업을 1억명이 한다면 
45억배 빠른 샘입니다.


코딩이 할말한 일인가는?
수동으로 하는데 걸리는 시간과
자동으로 하는데 걸리는 시간의
대소관계에 따라서 결정되는 것 같습니다.

-출처 생활코딩 유튜브 커뮤니티
profile
공유하고 나누는걸 좋아하는 개발자

0개의 댓글