본문 바로가기
React/TS

TypeScript 가이드

by 강깅꽁 2020. 10. 14.

TypeScript는 정적인 언어로 컴파일 시에 JavaScript파일을 생성한다.

또한, JavaScript의 슈퍼셋으로 JavaScript가 가지고 있는 모든 기능을 포함하고 있다. 

 

왜 써야하는가? 

JS는 동적이다. const, var, let같은 변수 선언 키워드만 보더라도 타입이 없다. 

이러한 동적 타입은 팀원과의 협업 뿐만 아니라 심지어 혼자 개발할 때에도 개발에 혼동을 주기가 쉽다. 

또한 런타임 에러가 발생하는 요인이기도 하다. 

 

한 예로, 아래와 같은 코드가 있을 때 addTwo라는 함수는 리턴 값으로 string을 반환한다.

하지만 개발자가 함수의 return 값을 숫자 타입으로 생각하고 다음과 같이 log를 출력하면 원하지 않은 결과가 출력된다.

function addTwo(one, two){
	return `합은 ${one+two}입니다.`
 };
 
 console.log("세 변수의 합은 "+addTwo() + 3);

 

TS는 정적이다. 초기에 러닝 커브가 있더라도 변수가 어떤 타입을 가지고 있는지 쉽게 파악할 수 있으며 컴파일을 통해 에러를 미리 확인해 줄 수 있다. 

 

아래와 같은 코드는 만일 addTwo라는 함수 내용을 몰라도 Code Editor 또는 컴파일 시에 에러를 확인할 수 있다. 

function addTwo(one: number , two: number): number {
	return `합은 ${one+two}입니다.`
 };
 
 console.log(addTwo() + 3);

 

TS의 타입

number, string, boolean, undefind, null, object, symbol와 같은 기본 JS의 타입들을 지원해준다.

 

기본 사용방법

선언할 때 변수 뒤에 : number와 같이 타입 어노테이션을 추가해주면 타입 선언이 완료된다.

any타입에는 어떠한 타입의 값이든 할당할 수 있다.

기본 타입

let numValue: number = 10; // 숫자 타입
let strValue: string = "abc"; // 문자열 타입
let boolValue: boolean = true; // 불린 타입
let objectValue: object = {}; // 객체 타입
let undefinedValue: undefined;
let nullValue: null = null;
let symboleValue: symbol = Symbol();
let anyValue: any = 123; 
anyValue = "abc";

 

배열 및 튜플 타입

튜플 타입은 배열 원소의 갯수와 타입을 미리 지정해줄 수 있다.

let strArr: string[] = ['abc', 'def']; //문자열 배열 타입
let tuple: [number, string]  = [123, 'abc']; // 튜플 타입

 

Interface

인터페이스는 새로운 타입을 만드는 것으로 인터페이스에서는 프로퍼티나 메소드를 선언할 수 있다.

interface Person {
    age: number,
    name: string,
    // 값이 필수적이지 않음 optional
    money?: number,
    sleep(from: number, to: number): void,
}

const Choi: Person = {
    age: 24,
    name: "choi",
    sleep(from, to){
        console.log(`${from}부터 ${to}까지 잠자기`);
    }
}

const Lee: Person = {
    age: 25,
    name: "lee",
    money: 200000,
    sleep(from, to) {
        console.log(`${from}부터 ${to}까지 집에서 잠자기`);
    }
}

console.log(Choi);
console.log(Lee);

 

함수

파라미터 값 및 리턴 값의 타입을 다음과 같이 표현할 수 있다.

place 파라미터는 값 할당 시에 String 타입의 값이 할당되면서 타입이 String으로 정해지기 때문에 Type annotation이 필요 없다.

function study(content: string, time: number, place = '집'): string { 
    return `${place}에서 ${time}시간 동안 ${content}를 공부합니다.`
}

const study2 = (content: string, time: number, place = '집'): string => {
    return `${place}에서 ${time}시간 동안 ${content}를 공부합니다.`
}

study('English', 2);
study('Computer', 3, 'cafe');
study2('Programming', 1, '대학');

 

함수 오버로딩

TS에서 함수 오버로딩은 자바에서의 오버로딩과 비슷하다. 

매개변수 타입이나 개수에 따라 리턴 값을 다르게 설정할 수 있다. 


interface a {
    a: '해동하여 드셔야 하는 식품입니다.'
}
interface b {
    b: '바로 섭취 가능한 식품입니다.'
}
// 함수 시그니쳐 선언
function refrigerator(food: '냉장식품'): a;
function refrigerator(food: '냉동식품'): b;

function refrigerator(food: '냉장식품' | '냉동식품'): any {
    if(food === '냉장식품') {
        return {
            a: '해동하여 드셔야 하는 식품입니다.'
        }
    } else if(food === '냉동식품') {
        return {
            b: '바로 섭취 가능한 식품입니다.'
        }
    } else {
        throw new Error('해당되지 않는 음식이 들어왔습니다.')
    }
}

const resultA = refrigerator('냉장식품');
const resultB = refrigerator('냉동식품');
console.log(resultA);
console.log(resultB);

열거형 Enums

상수 값들을 간편하게 정의할 수 있다.

값을 할당하지 않으면 선언 순서대로 번호가 매겨진다.

enum LolTier {
    BRONZE="BRONZE",
    SILVER="SILVER",
    GOLD="GOLD",
}

enum LolTier2 {
    BRONZE, 
    SILVER, 
    GOLD,
}
/*
{
  '0': 'BRONZE',
  '1': 'SILVER',
  '2': 'GOLD',
  BRONZE: 0,
  SILVER: 1,
  GOLD: 2
}
*/