Typescript/TypeScript(ZeroCho)

TS 모듈 시스템의 주의사항

느리지만 꾸준하게 2021. 10. 21. 20:33

파일중에 import나 export가 들어있으면 모듈이 되는 것이고 import나 export가 없으면 script가 되는 것이다.

 

즉 아래와 같이 export를 맨앞에다가 각각 넣는 순간 모듈이 되는 것이다. 그래서 모듈들을 다른파일에서 가져다가 쓸 수 있게 되는 것이다.

// types.ts

export interface Card {
    att: number;
    hp: number;
    mine: boolean;
    field: boolean;
    cost?: number;
    hero?: boolean;
}

export class Hero implements Card {
    public att: number;
    public hp: number;
    public hero: boolean; 
    public field: true;
    public mine: boolean;
    constructor(mine: boolean) {
        this.mine = mine;
        this.att = Math.ceil(Math.random() * 2);
        this.hp = Math.ceil(Math.random() * 5) + 25;
        this.hero = true;
        this.field = true;
    }
};

export class Sub implements Card {
    public att: number; // number | undefined
    public hp: number;
    public field: boolean = false;
    public mine: boolean;
    public cost: number;
    constructor(mine: boolean) {
        this.mine = mine;
        this.att = Math.ceil(Math.random() * 5);
        this.hp = Math.ceil(Math.random() * 5);
        this.cost = Math.floor((this.att + this.hp) / 2);
    }
}

....

types.ts파일을 만들어서 lecture.ts에서 만든 것을 몇개 꺼내와보자. 분리를 했기 때문에 types.ts에서 오류나는 것들을 구현을 해주어야한다. 

// types.ts

export interface Card {
    att: number;
    hp: number;
    mine: boolean;
    field: boolean;
    cost?: number;
    hero?: boolean;
}

export interface Player {
    hero: HTMLDivElement
    deck: HTMLDivElement
    field: HTMLDivElement
    cost: HTMLDivElement
    deckData: Sub[]
    heroData?: Hero | null
    fieldData: Sub[]
    chosenCard?: HTMLDivElement | null
    chosenCardData?: Card | null
}

export class Sub implements Card {
    public att: number;
    public hp: number;
    public cost: number; 
    public field: true;
    public mine: boolean;
}

export class Hero implements Card {
    public att: number;
    public hp: number;
    public hero: boolean; 
    public field: true;
    public mine: boolean;
}

즉 type과 class들만 import 해준다.

// lecture.ts

import { Card, Player } from './types';

 

다시 상기시키자. default랑 module.exports는 다르다. common.js랑 es2015의 차이를 명확히 알자.

 

common js를 위한 import를 알아보자. typescript에서는 common.js에 해당하는 type을 하나 만들어준다. 그렇게 해야 typescript에서 쓸 수 있기 때문이다.

// common.js

module.exports = function() {
    console.log('hi');
}

위에 해당하는게 common.d.ts에서는 아래와 같이 되어있다.(d.ts는 보통 내 프로젝트가 라이브러리일 때 사용한다.)

(d.ts는 ambient(주변의) module라고 부른다.)

// common.d.ts

declare function a() {}
export = a;

그래서 es2015를 import하는 방식과 common.js를 import 하는 방식이 다르다.

 

아래에 *(asterisk)는 거기에 해당하는 모든 것을 가져온다는 뜻이다. 그 파일의 있는 모든 모듈을 A라는 이름 아래 가져온다는 뜻.

// lecture.ts

import { Card, Player } from './types'; // es2015를 import하는 방법
import A = require('./common'); // common.js를 import 하는 방법

// require를 대체할 수 있는것
import * as A from './common';

 

 

 

Redux, Axios등 남의 라이브러리 사용하기

common.js를 하는 경우는 내가 사용하는 경우에는 직접 만들일이 별로 없을 것이다. 대부분 아래와 같이 최신문법으로 만들 것이다.

// module.js

const hello = 'module';

export default hello;

 

JS 생태계가 common.js로 돌아간지 5~10년 정도 되었기 때문에 최신문법보다 common.js가 역사가 더 오래되었다. 그래서 대부분의 패키지들이 common.js로 되어있기 때문에 남의 라이브러리 쓸 때 조심해야 한다.

 

남의 라이브러리 & npm 패키지의 유형을 알아보자.

https://github.com/reduxjs/redux

리덕스 깃허브에 들어가보면 typescript가 가장 많이 차지하고 있다. 즉 리덕스 소스코드는 대부분 타입스크립트로 만들어져 있다.

redux-ts 76% js 19.5% css 4.5%

lecture 폴더에서 redux를 설치해보면 node_modules안에 redux안에 index.d.ts가 저절로 들어있다.

index.d.ts는 redux에 대한 type들을 쭉 만들어 놓은 것이다.

npm i redux

redux - index.d.ts

index.d.ts에 있는 거 몇개만 가져와보면 아래와 같다.

declare라는 것은 type이 없는 것을 새로 type을 선언할 때 declare를 써주는 것이다.

이렇게 d.ts파일을 만들어 주는 것을 ambient module이라고 한다.

export interface Action<T = any> {
  type: T
}

declare const $CombinedState: unique symbol

 

그리고 redux는 default가 없기 때문에 다 객체형식으로 구조분해식으로 가져온다.

import { combineReducers } from 'redux';

import { Action } from 'redux';

 

 

두번째로 괜찮은 라이브러리는 axios라는 라이브러리가 있다.

https://github.com/axios/axios

axios라는 라이브러리는 javascript가 가장 많은 비중을 차지하고 있다. 대부분 js로 만들어져서 type 지원 안하나? 생각할 수도 있다. 다행히 ts도 3.8%정도 있어서 index.d.ts파일이 있기 때문에 다행히 type을 지원을 한다.

만약에 타입을 지원을 하지 않으면 남의 라이브러리 코드를 내가 직접 짜야한다.

axios - js 93.4% ts 3.8% HTML 2.8%

export default axios가 있으니까 {} 중괄호 없이 import axios from "axios"로 쓸 수 있다.

// axios index.d.ts

// TypeScript Version: 3.0

export type AxiosRequestHeaders = Record<string, string>;

export type AxiosResponseHeaders = Record<string, string> & {
  "set-cookie"?: string[]
};

export interface AxiosRequestTransformer {
  (data: any, headers?: AxiosRequestHeaders): any;
}

....

declare const axios: AxiosStatic;

export default axios;

 

 

 

 

 

<출처 조현영: 웹게임을 만들며 배우는 TypeScript>

https://www.inflearn.com/course/%EC%9B%B9%EA%B2%8C%EC%9E%84%EC%9D%84-%EB%A7%8C%EB%93%A4%EB%A9%B0-%EB%B0%B0%EC%9A%B0%EB%8A%94-typescript/dashboard

 

웹 게임을 만들며 배우는 TypeScript - 인프런 | 강의

웹 게임을 만들며 배우는 자바스크립트의 후속작으로 같은 게임을 타입스크립트로 만들어봅니다., 타입스크립트, 웹 게임을 만들며 재밌게 배워보아요! 🗒 강의소개 웹 게임을 만들며 배우는

www.inflearn.com

 

'Typescript > TypeScript(ZeroCho)' 카테고리의 다른 글

커스텀 패키지 타이핑  (0) 2021.10.21
남의 패키지인 Redux & Axios 사용하기  (0) 2021.10.21
JS 모듈 시스템  (0) 2021.10.21
tsc 기본명령어  (0) 2021.10.21
ts 간단한 변경사항  (0) 2021.10.21