TYPESCRIPT

정은경·2024년 3월 6일
0

👸 Front-End Queen

목록 보기
256/266

웹 개발의 역사

1. 자바스크립트의 탄생

  • 1995년 넷스케이프의 브랜드 아이크(Brendan Eich)가 자바스크립트를 만듬
  • 자바스크립트는 C, 자바와 유사한 기본 문법을 가지고 있으며 별로 유명하지 않던 객체 지향 언어인 self의 프로토타입 기반 상속 개념과 Lisp 계열 언어 중 하나임 scheme의 일급 함수 개념을 차용한 경량의 프로그래밍 언어

2. 자바스크립트 표준 ECMAScript의 탄생

폴리필(polyfill)과 트랜스파일(transpile)
최신 기능을 구버전의 실행 환경에서 동작할 수 있게 바꿔주는 역할

  • 폴리필
    브라우저가 지원하지 않는 코드를 브라우저에서 사용할 수 있도록 변환한 코드 조각이나 플러그인을 말함
    예) core.js, pollyfill.io
  • 트랜스 파일
    최신 버전 코드를 예쩐 버전의 코드로 변환하는 과정을 말함
    예) babel
  • 넷스케이프는 컴퓨터 시스템의 표준을 관리하는 Ecma 인터내셔널(국제 표준화 기구)에 자바스크립트의 표준화를 위한 자바스크립트 기술 규격을 제출
  • Ecma 인터내셔널은 ECMAScript라는 이름으로 자바스크립트 표준화를 공식화함
  • 자바스크립트가 표준화되자 정적이던 웹사이트에서 동적인 웹 애플리케이션으로의 전환이 가속화됨

3. 웹사이트에서 웹 애플리케이션으로의 전환

웹사이트

  • 웹사이트는 수집된 데이터 및 특정 페이지에 표시하기 위한 정적인 웹
  • 단방향으로 정보를 제공하기 때문에 사용자와 상호 작용하지 않으며, HTML에 링크가 연결된 웹 페이지 모음으로 콘텐츠가 동적으로 업데이트되지 않음

웹 애플리케이션

  • 사용자와 상호작용하는 쌍방향 소통의 웹
  • 검색, 댓글, 채팅, 좋아요 기능 등 웹 페이지 내부에 수많은 애플리케이션이 동작하고 있기 때문에 웹 애플리케이션라고 부름

4. 개발 생태계의 발전

  • 대규모 웹 서비스 개발의 필요성이 커지면서 하나의 웹 페이지를 통으로 개발하는 것이 아니라, 컴포넌트 단위로 개발하는 방식이 생겨남
  • Ajax로 페이지 전체를 새로고침하지 않아도 자바스립트의 비동기 요청을 사용해서 페이지의 일부 데이터를 로드할 수 있게 됨

    컴포넌트 베이스 개발 (Component Based Development, CBD)

  • 재사용할 수 있는 컴포넌트를 개발 또는 조합해서 하나의 애플리케이션을 만드는 개발 방법론
  • 서비스에 다루는 데이터를 구분하고 그에 맞는 UI를 표현할 수 있게 컴포넌트 단위로 개발하는 접근 방식
  • 컴포넌트는 모듈과 유사하게 하나의 독립된 기능을 재상요하기 위한 코드 묶음. 다만 모듈과는 달리 런타임 환경에서 독립적으로 배포.실행될 수 있는 단위. 따라서 컴포넌트는 다른 컴포넌트와의 의존성을 최소화하거나 없애나 함

5. 개발자 협업의 필요성 증가

  • 결과물이 커졌기 때문에 서비스를 개발하고 나서 유지보수를 하는 데 협업의 중요성도 높아졌음

자바스크립트의 한계

1. 동적 타입 언어

  • 변수에 타입을 명시적으로 지정하지 않고 코드가 실행되는 런타임에 변수값이 할당될 때 해당 값의 타입에 따라 변수 타입이 결정된다는 것을 의미

2. 동적 타이핑 시스템의 한계

3. 한계 극복을 위한 해결 방안

  1. JSDOc
  • 모듈, 네임스페이스, 클래스, 메서드, 매개변수 등에 대한 API 문서 생성 도구
  • 주석에 @ts-check를 추가하면 타입 및 에러 확인이 가능하며 자바스크립트 소스코드에 타입힌트를 제공하는 HTML 문서를 생성할 수 있음
  • 주석의 성격을 지니고 있기 때문에 강제성을 부여하기는 어렵다
  1. propTypes
  • 리액트에서 컴포넌트 props의 타입을 검사하기 위해 사용하는 속성
  • prop에 유효한 값이 전달되었는지 확인할 수 있지만, 전체 애플리케이션의 타입 검사를 하는 데는 사용할 수 없음
  1. Dart
  • 구글이 자바스크립트를 대체하기 위해 제시한 새로운 언어로 타이핑이 가능

4. 타입스크립트의 등장

  • 마이크로소프트는 자바스크립트의 슈퍼셋 언어인 타입스크립트를 공개
  • 다트와 달리 자바스크립트 코드를 그대로 사용할 수 있었고, 아래와 같은 단점을 극복할 수 있었음

Superset

  • 기존 언어에 새로운 기능과 문법을 추가해서 보완하거나 향상하는 것
  • 슈퍼셋 언어는 기존 언어와 호환되며 일반적으로 컴파일 등으로 기존 언어 코드로 변환되어 실행됨
  • 안전성 보장
    • 타입스크립트는 정적 타이핑을 제공
    • 컴파일 단계에서 타입 검사를 해주기 때문에 자바스크립트를 사용했을 때 빈번하게 발생하는 타입 에러를 줄일 수 있음
    • 런타임 에러를 사전에 방지할 수 있어 안정성이 크게 높아짐
  • 개발 생산성 향상
    • VSCode 등 IDE에서 타입 자동 완성 기능을 제공
    • 이 기능으로 변수와 함수 타입을 추론할 수 있음
    • 리액트를 사용할 때 어떤 prop을 넘겨야 하는지 매번 확인하지 않아도 사용부에서 바로 볼 수 있기 때문에 개발 생산성이 크게 향상됨
  • 협업에 유리
    • 타입스크립트를 사용하면 복잡한 애플리케이션 개발.협업에 유리
    • 타입스크립트는 인터페이스, 제네릭 등을 지원하는데 인터페이스가 기술되면 코드를 더 쉽게 이해할 수 있게 도와줌
    • 복잡한 애플리케이션일수록 협업하는 개발자 수도 증가하는데 자동 완성 기능이나 기술된 인터페이스로 코드르 쉽게 파악할 수 있음

타입스크립트 interface

  • 객체 구조를 정의하는 역할
  • 특정 객체가 가져야 하는 속성과 메서드의 집합을 인터페이스로 정의해서 객체가 그 구조를 따르게 함
  • 자바스크립트에 점진적으로 적용 가능
    • 타입스크립트는 자바스크립트의 슈퍼셋이기 때문에 일괄 전환이 아닌 점진적 도입이 가능
    • 전체 프로젝트가 아닌 일부 프로젝트, 그중에서도 일부 기능부터 점진적으로 도입해볼 수 있음

비동기 호출

비동기 처리를 다룰 때 고려사항

  • 현재 비동기 동작이 어떤 상태인가?
  • 비동기 동작을 위해 필요한 정보가 무엇인가?
  • 요청이 성공했다면 받아온 정보를 어떻게 저장하고 관리할 것인가?
  • 요청이 실패했다면 실패에 대한 정보를 어떻게 확인할 것인가?
  • 비동기 요청에 대한 코드를 쉽게 유지보수할 수 있도록 어떻게 구조화하고 관리할 것인가?

API 요청

  1. fetch로 API 요청하기
  2. 서비스 레이어로 분리하기
  3. Axios 활용하기
  4. Axios 인터셉터 사용하기
  5. API 응답 타입 지정하기
  6. 뷰 모델 (View Model) 사용하기
  7. Superstruct를 사용해 런타임에서 응답 타입 검증하기
  8. 실제 API 응답 시의 Superstruct 활용 사례

타입스크립트 왜 배워야 할까?

  • 오류 예방
    • 컴파일 단계에서 타입을 검사하기 때문에 실행 단계에서 발생할 수 있는 오류를 사전에 발견하고 수정할 수 있음
  • 코드 가독성과 유지보수성 향상
    • 타입을 명시적으로 지정함으로써 코드의 의미를 명확하게 표현할 수 있고, 코드의 재사용성과 유지보수성을 높일 수 있음
  • 협업 효율성 향상
    • 타입을 통해 코드의 의도를 명확하게 전달할 수 있기 때문에 협업 효율성을 높일 수 있음
  • 자바스크립트와 호환
    • 타입스크립트는 자바스크립트와 100% 호환되기 때문에 자바스크립트가 사용되는 어떤 곳이든 타입스크립트를 사용할 수 있음

1. 타입스크립트 (typescript)

  • 자바스크립트에 타입을 부여한 언어 (자바스크립트를 확장한 언어)
  • 타입스크립트는 미국 마이크로소프트에서 개발한 오픈소스 언어
  • C#, 델파이, 터보 파스칼을 만든 개발자가 만듬
  • 타입스크립트에서 제공하는 모듈 시스템을 효과적으로 사용하려면 웹팩(webpack) 등 모듈 번들러도 이해해야 함
  • 웹브라우저에서 타입스크립트 파일을 바로 인식할 수 없어, 웹브라우저에서 실행시에는 타입스크립트 파일을 자바스크립트로 변환(컴파일, compile)한 것으로 실행해야함
node ./node_modules/typescript/bin/tsc index.ts

2. 타입스크립트의 매력포인트

  1. 에러의 사전 방지
  2. 코드 가이드 및 자동 완성
    • vscode를 사용할 때, 변수 타입의 추론을 기반으로 한 인텔리센스(IntelliSense) 사용 가능
    • 예) number 타입인 변수라면, number 타입이 사용할 수 있는 API를 쉽게 확인할 수 있으며 tab을 눌러서 해당 API를 빠르게 자동완성할 수 있음

3. 타입스크립트의 현실적인 대안 JSDoc

  • 자바스크립트 코드에 주석을 다는 표준 방식
  • Java 소스 코드에서 HTML 형식의 API 문서를 생성하고자 썬 마이크로시스템즈(Sun Microsystems)에서 제작한 주석화 도구인 JavaDoc과 유사한 형태
  • 고유한 문법을 가짐
  • 에러를 사전에 방지해줌 예) 함수에 입력된 파라미터의 타입체크
  • 타입이 지정된 변수에서 사용할 수 있는 API 속성을 볼 수 있음
  • string, number, boolean 등 간단한 타입이 아니라 객체와 배열 더 나아가 복잡한 타입을 다룰 때는 타입 정의를 위해 작성해야하는 코드가 많아짐 (타입스크립트의 모듈 시스템을 사용하지 않는다면 파일마다 동일한 코드를 중복으로 작성해햐하는 단점 생김)
// @ts-check

/**
 * @description 두 수의 합을 구하는 함수
 * @param {number} a 첫 번째 숫자
 * @param {number} b 두 번째 숫자
*/
function sum(a, b){
  return a + b;

4. 타입스크립트 기본 타입들

  • string, number, boolean, object, Array, tuple, any, null, undefined

튜플 타입 (tuple)

  • 튜플은 특정 형태를 갖는 배열을 의미
  • 배열의 길이가 고정되고 각 요소 타입이 정의된 배열
var items: [string, number] = ['hi', 11];

null과 undefined

  • null과 undefined 타입은 타입스크립트 설정 파일의 strict 옵션에 따라서 사용 여부가 결정됨
  • strict 옵션이 꺼져 있을 때는 신경 쓰지 않아도 되는 타입!

인터페이스 vs. 타입

interface

  • 이름을 똑같이 선언했을 때 자동확장 가능 (선언병합)
  • 주로 객체의 타입을 설정할 때 사용

type

  • type: 기존에 존재하는 타입을 이름만 바꿔서 사용 가능 (type alias)
  • 객체가 아닌 primitive type일 때
  • 병렬적인 관계라면 type으로
  • 함수반환형에서는 shorthand라서 더 좋음!


5. 인터페이스 (interface)

  • 타입스크립트에서 인터페이스는 객체 타입을 정의할 때 사용하는 문법

인터페이스 상속

상속
상속이란 객체 간 관계를 형성하는 방법
상위(부모) 클래스의 비용을 하위(자식) 클래스가 물려받아 사용하거나 확장하는 기법

  • 자바스크립트에서의 상속
    • class Persion {
      	constructor(name, age){
          	this.name = name;
              this.age = age;
          }
          
          logAge() {
          	console.log(this.age);
          }
      }
      
      class Developer extends Person {
      	constructor(name, age, skill) {
          	super(name, age);
              this.kill = skill;
          }
          
          logDeveloperInfo() {
          	this.logeAge();
              console.log(this.name);
              console.log(this.skill);
          }
      }
  • 타입스크립트 인터페이스 상속
    • interface Person {
      	name: string;
         age: number;
      }
      
      interface Developer extends Person {
      	skill: string;
      }
      
      var ironman: Developer = {
      	name: "ironman",
         age: 21,
         skill: "ironning",
         power: true
      }

인터페이스를 이용한 인덱싱 타입 정의

인덱싱
객체의 특정 속성을 접근하거나
배열의 인덱스로 특정 요소에 접근하는 동작을 의미

var user = {
    name: 'jek',
    admin: true,
};
console.log(user['name']); // jek
var companies = ['삼성', '네이버', '구글'];
console.log(companies[0]); // 삼성
  • 배열의 인덱싱 타입 정의
interface StringArray {
	[index: number] : string;
}

var companies: StringArray = ['samsung', 'naver', 'google'];
  • 객체 인덱싱 타입 정의
interface ScoreMap {
	[level: string]: number;
}

var score: ScoreMap = {
	good: 80
};

인덱스 시그니처 (index signature)

  • 정확히 속성 이름을 명시하지 않고 속성 이름의 타입과 속성의 값의 타입을 정의하는 문법
interface ScoreMap {[level: string]: string;}
  • 객체의 속성과 이름과 속성 값이 정해져 있는 경우에는 속성 이름과 속성 값 타입을 명시해서 정의하고, 속성 이름은 모르지만 속성 이름의 타입과 값의 타입을 아는 경우에는 인덱스 시그니처를 활용

6. 연산자를 사용한 타입 정의

유니언 타입 (union type)

  • 여러 개의 타입 중 한 개만 쓰고 싶을 때 사용하는 문법
  • OR 연산자(|)를 이용하여 여러 개의 타입 중 1개를 사용하겠다고 선언하는 방식
function logText(text: string | number) {
	console.log(text);
}
  • any를 사용하는 것 보다는 변수에서 사용할 타입을 구체적으로 정확하게 선언함으로써 중복된 코드를 줄이고(함수마다 단입 타입을 정의하여 함수 여러개 정의) 타입스크립트의 장점(자동으로 속성과 API를 자동완성하는)을 살릴 수 있음!
  • 함수 파라미터에 유니언 타입을 사용하면 함수에 어떤 값이 들어올지 알 수 없기 때문에 가장 안전한 방식으로 타입의 속성과 API를 자동완성해 줌
function logText(text: string | number) {
	if(typeof text === 'string') {
    	console.log(text.toUpperCase());
    }
  	if(typeof text === 'number') {
    	console.log(text.toLocalString());
    }
  
  	console.log("");
} 
  • 함수의 파라미터에 유니언 타입을 선언하면 함수 안에서는 두 타입의 공통 속성과 메서드만 자동 완성됨
  • 특정 타입의 속성과 메서드를 사용하고 싶다면 typeof나 in 연산자를 사용하여 타입을 구분한 후 코드를 작성해야 함 (타입 가드)

타입 가드

  • 타입을 구분한 후 코드를 작성하는 것

인터섹션 타입 (intersection type)

  • 타입 2개를 하나로 합쳐서 사용할 수 있는 타입
  • 보통 인터페이스 2개를 합치거나 이미 정의된 타입 여러 개를 하나로 합칠 때 사용
interface Avenger {
	name: string;
}

interface Hero {
	skill: string;
}

function introduce(someome: Avenger & Hero) {
	console.log(someone.name);
  	console.log(someone.skill);
}

타입 별칭 (type alias)

  • 타입 별칭은 특정 타입이나 인터페이스 등을 참조할 수 있는 타입변수를 의미
  • 타입에 의미를 부여해서 별도의 이름으로 부르는 것
  • 타입 별칭의 이름이 중복되면 타입 에러 표시됨에 주의!
  • 자바스크립트의 변수처럼 해당 타입이 어떤 역할을 하는지 이름을 짓고 싶을 때 사용할 수도 있고, 여러 번 반복되는 타입을 변수해서 쉽게 표기하고 싶을 때도 사용
// type MyName = string;
// var capt: string = 'jek';

type MyName = string;
var capt: MyName = 'jek';
  • 타입 별칭을 썼을 때 가장 큰 장점은 반복되는 타입 코드를 줄여 줄 수 있다는 것
/** 타입 별칭 사용전
function logText(text: string | number) {
	// ...
}

var message: string | number = '안녕하세요';
logText(message);
**/

// 타입 별칭 사용후
// string | number 타입을 MyMessage 라는 타입 별칭으로 정의하고, 
// 반복되는 코드를 줄였을 뿐 아니라 
// string|number 타입이 내 메시지에 사용되는 타입이라는 의미도 부여함!
// 타입 별칭을 사용하면 타입에 의미를 담아 여러 곳에 재사용할 수 있음!
type MyMessage = string | number;
function logText(text:Message){
	// ...
}
var message: MyMessage = '안녕하세요';
logText(message);

type vs. interface

  • 코드 에디터에서 표기 방식 차이

  • 인터페이스는 주로 객체 타입을 정의하는 데 사용하는 반면
  • 별칭은 일반 타입에 이름을 짓는 데 사용할 수 있음
  • 별칭은 제네릭이나 유틸리티 타입 등 다양한 타입에 사용할 수 있음

타입 확장

  • 타입 확장이란 이미 정의되어 있는 타입들을 조합해서 더 큰 의미의 타입을 생성하는 것
  • 타입 별칭과 인터페이스는 타입을 확장하는 방식이 다름
    * 인터페이스 => 상속이라는 개념사용하여 확장
    • 별칭 => 인터섹션 타입으로 객체 타입을 2개 합쳐서 사용

인터페이스의 '선언 병합'(declaration merging)

  • 인터페이스는 동일한 이름으로 인터페이스를 선언하면 인터페이스 내용을 합치는 특성이 있음

interface에는 x in dict 타입 사용 불가

타입 별칭은 언제 쓰는 것이 좋을까?

  • 2021년 이전의 타입스크립트 공식문서에서는 '좋은 소프트웨어는 확장이 용이해야 한다(open-closed principle)'는 관점에서 타입 별칭보다 인터페이스의 사용을 권장했음

  • 하지만 2023년 공식 문서에는 이 내용이 없고, 일단 인터페이스를 주로 사용해보고 타입 별칭이 필요할 때 타입 별칭을 쓰라고 안내함

  • 실제로 두 문법을 사용하다 보면 '타입 별칭으로만 타입 정의가 가능한 곳에서는 타입 별칭을 사용하고 백엔드와의 인터페이스를 정의하는 곳에는 인터페이스를 이용하자'는 결론이 나온다고함! (쉽게 시작하는 타입스크립츠 책 저자 왈)

    • 타입 별칭으로만 정의할 수 있는 타입들
      • 주요 데이터 타입, 인터섹션, 유니언 타입
      • type MyString = string;
        type StringOrNumber = string | number;
        type Admin = Person & Developer;
        			~~~
      • 타입 별칭은 제네릭(generic), 유틸리티 타입(utility type), 맵드 타입(mapped type)과도 연동하여 사용할 수 있음
      • 제네릭은 인터페이스와 타입 별칭오 모두 사용할 수 있지만, 유틸리티 타입이나 맵드 타입은 타입 별칭으로만 정의할 수 있음
      • // 제네릭
        type Dropdown<T> = {id: string; title: T;};
        // 유틸리티 타입
        type Admin = {name: string; age: number; role: string;};
        type OnlyName = Pick<Admin, 'name'>
        // 맵드 타입
        type Picker<T, K extends keyof T> = {[P in K]: T[P];}
    
    * 백엔드와의 **인터페이스** 정의
      * 백엔드/프론트엔드 간에 어떻게 데이터를 넘길지 정의하는 작업을 '인터페이스를 정의한다'라고 함
      * 여기에서 인터페이스는 영역 간 접점(데이터)을 서로 맞추는 작업을 의미함
      * 백엔드에서 전달받은 데이터의 타입을 정의할 때 타입스크립트 인터페이스를 사용한다면 (타입 별칭을 사용할 수는 있지만) 기존 타입의 확장이라는 측면에서 인터페이스로 정의하는 것이 더 수월함
      * 유연하게 타입을 확장하는 관점에서는 타입 별칭보다 인터페이스가 더 유리함

7. 이넘 (enum)

  • 이넘은 C, JAVA 등 다른 프로그래밍 언어에도 있는 데이터 타입

  • 타입스크립트에서는 이넘을 지원함 (자바스크립트에는 없음)

  • 이넘은 특정 값의 집합을 의미하는 데이터 타입, 상수 집합이로고도 표현함

    상수 (constant)

  • 변하지 않는 고정 값을 '상수'라고 함

  • 상수는 단순히 고정된 값을 저장하는 것뿐만 아니라 이 값이 어떤 의미를 갖는지 알려줌으로써 가독성을 높이는 장점이 있음

  • 보통 모두 대문자로 작성해서 일반 변수와 구분함

숫자형 이넘

  enum Direction {
  	Up, 	// 0
  	Down,	// 1
  	Left,	// 2
  	Right	// 3
  }
  
  console.log(Direction.up); // 0

8. 자바스크립트 모듈

  • 자바스크립트는 태생적으로 모듈이라는 개념이 없던 프로그래밍 언어
  • 파일별로 변수나 함수를 구분해서 정의하더라도 기본적으로 모두 전역 유효 범위(global scope)를 갖는 것이 자바스크립트의 특징

과거 자바스크립트 모듈화를 위한 시도(1): Common.js

  • Common.js는 브라우저뿐만 아니라 브라우저 이외의 환경인 서버, 데스크톱에서도 자바스크립트를 활용하려고 고안된 스펙이자 그룹
  • 현재는 서버 런타임 환경인 Node.js에서 가장 활발하게 사용되고 있는 스펙! Node.js가 설치되어 있다면 별도의 도구나 라이브러리 없이도 아래의 문법을 이용하여 자바스크립트의 모듈화를 실현할 수 있음
// math.js
function sum(a, b) {
	return a + b;
}

module.exports = {
	sum
};

// app.js
var math = require('./math.js');

console.log(math.sum(10, 20)); // 30

과거 자바스크립트 모듈화를 위한 시도(1): Require.js

  • Require.js는 AMD(Asynchronous Module Definition)라는 비동기 모듈 정의 그룹에서 고안된 라이브러리 중 하나
  • 비동기 모듈은 애플리케이션이 시작되었을 때 모든 모듈을 가져오는 것이 아니라 필요할 때 순차적으로 해당모듈을 가져온다는 의미
  • 다음과 같이 라이브러리르 로드해서 사용해야 함
<html>
  <head></head>
  <body>
  	<!-- 라이브러리 파일 다운로드 후 다음과 같이 연결 -->
    <script src="require.js"></script>
    <script>
    	require(["https://unpkg.com/vue@3/dist/vue.global.js "], function() {
      		console.log("vue is loaded");	
      	});
    </script>
  </body>
</html>
  • require()라는 문법을 이용하여 외부 라이브러리를 마치 모듈처럼 가져오는 형태로 사용할 수 있음

2015년 자바스크립트(ES6) 언어레벨에서 모듈화 개념 지원!

  • 언어 레벨에서 지원되지 않는 모듈화 개념을 자바스크립트 생태계에서 풀려는 시도가 많아지자 2015년에 처음으로 언어레벨에서 지원됨! 그것이 바로 import/export 문법!
// math.js
function sum(a, b) {
	return a + b;
}

export { sum }

// app.js
import { sum } from "./math.js";
console.log(sum(10, 20));
  • export default 구문은 하나의 대상만 모듈에서 내보내고 싶을 때 사용
// math.js
function sum(a, b) {
	return a + b;
}

export default sum;

// app.js
import sum from "./math.js";
console.log(sum(10, 20));
  • import as를 이용하면 가져온 변수나 함수의 이름을 해당 모듈 내에서 변경하여 사용할 수 있음
// math.js
function sum(a, b) {
	return a + b;
}

export { sum }

// app.js
import { sum as add } from "./math.js";
console.log(add(10, 20));
  • import * 문법을 사용해서 특정 파일에서 내보낸 기능이 많아 가져와야 할 것이 많을 때 편리하게 사용할 수 있음
// math.js
function sum(a, b) {
	return a + b;
}

function substract(a, b) {
	return a - b;
}

function divide(a, b) {
	return a / b;
}

export { sum, substract, divide }

// app.js
import * as myMath from "./math.js"
console.log(myMath.sum(10, 20)); // 30
console.log(myMath.subtract(30, 10)); // 20
console.log(myMath.divide(4, 2)); // 2

타입스크립트 모듈 유효 범위

  • 자바스크립트가 변수를 선언할 때 기본적으로 전역 변수로 선언되듯이 타입스크립트 역시 전역 변수로 선언됨

타입스크립트 모듈화 문법

  • import type
// hero.ts
interface Hulk {
	name: string;
  	skill: string;
}

export { Hulk };

// app.ts
import type { Hulk } from "./hero";

var banner: Hulk = {
	name: "배너",
  	skill: "화내기",
};
  • import inline type
// hero.ts
interface Hulk {
	name: string;
  	skill: string;
}

function smashing() {
	return '';
};

var doctor = {
	name: "스트레인지"
};

export { Hulk, smashing, doctor };

// app.ts
import type { type Hulk, doctor, smashing } from "./hero";

var banner: Hulk = {
	name: "배너",
  	skill: "화내기",
};
  • 모듈화 전략: Barrel
    • 배럴이란 여러 개의 파일에서 가져온 모듈을 마치 하나의 통처럼 관리하는 방식
// ./hero/hulk.ts
interface Banner {
	name: string;
}

export { Banner }

// ./hero/ironman.ts
interface Tony {
	name: string;
}

export { Tony }

// ./hero/captain.ts
interface Steve {
	name: string;
}

export { Steve }

// ./hero/index.ts
import { Banner } from './hulk';
import { Tony } from './ironman';
import { Steve } from './captain';

export { Banner, Tony, Steve };

// app.ts
// import { Banner } from "./hero/hulk";
// import { Tony } from "./hero/ironman";
// import { Steve } from "./hero/captain";
import { Banner, Tony, Steve } from "./hero";

var banner: Banner = { name: "배너" };
var tony: Tony = { name: "토니" };
var steve: Steve = { name: "스티브" };

9. 유틸리티 타입 (utility type)

  • 유틸리티 타입은 이미 정의되어 있는 타입 구조를 변경하여 재사용하고 싶을 때 사용하는 타입
  • 타입스크립트에서 미리 정의해 놓은 내장 타입이기 때문에 타입스크립트를 설치한 후 타입스크립트 설정 파일의 lib 속성만 변경해 주면 바로 사용할 수 있음
// tsconfig.json
// * 최신 자바스크립트 문법을 의미하는 ESNext를 추가
{
	"compilerOptions": {
    	"lib": ["ESNext"]
    }
}
  • lib 속성은 타입스크립트에서 미리 정의해 놓은 타입 선언 파일을 사용할 때 쓰는 옵션

9-1. Pick 유틸리티 타입

interface Profile {
  id: string;
  address: string;
}

type ProfileId = Pick<Profile, "id">;

let captainProfile: ProfileId = {
  id: "캡틴 아이디",
};

console.log(captainProfile);

interface UserProfile {
  id: string;
  name: string;
  address: string;
}

type HulkProfile = Pick<UserProfile, "id" | "name">;

let hulk: HulkProfile = {
  id: "1",
  name: "hulk",
};
  • Pick 타입으로 이미 존재한느 타입의 특정 속성만 추출해서 새로운 타입으로 정의할 수 있음

Pick 타입 문법

Pick<대상타입, '대상타입의 속성 이름'>
Pick<대상타입, '대상타입의 속성 1 이름' | '대상타입의 속성 2 이름'>

9-3. Omit 유틸리티 타입

  • Omit 타입은 특정 타입에서 속성 몇 개를 제외한 나머지 속성으로 새로운 타입을 생성할 때 사용하는 유틸리티 타입

Omit<대상타입, '대상타입 속성 이름'>
Omit<대상타입, '대상타입의 속성 1 이름' | '대상타입의 속성 2 이름'>

interface UserProfile {
  id: string;
  name: string;
  address: string;
}

type User = Omit<UserProfile, "address">;

let user = {
  id: "1",
  name: "사용자",
};

9-4. Partial 유틸리티 타입

  • Partial 타입은 특정 타입의 모든 속성을 모두 옵션 속성으로 변환한 타입을 생성해 줌
  • 주로 HTTP PUT처럼 데이터를 수정하는 REST API를 전송할 때 종종 사용되는 타입

Partial<대상타입>

interface Todo {
  id: string;
  title: string;
}

type OptionTodo = Partial<Todo>;

9-5. Exclude 유틸리티 타입

  • Exclude 타입은 유니언 타입을 구성하는 특정 타입을 제외할 때 사용

Exclude<대상유니언타입, '제거할 타입이름'>
Exclude<대상유니언타입, '제거할 타입이름 1' | 제거할 타입이름 2'>

type Languages = "C" | "Java" | "TypeScript" | "React";
type TrueLanguages = Exclude<Languages, "React">;
type WebLanguages = Exclude<Languages, "C" | "JAVA" | "React">;

9-6. Record 유틸리티 타입

  • Record 타입은 타입 1개를 속성의 키(key)로 받고 다른 타입 1개를 속성 값(value)으로 받아 객체 타입으로 변환
type HeroProfile = {
  skill: string;
  age: number;
};
type HeroNames = "thor" | "hulk" | "capt";

type Heroes = Record<HeroNames, HeroProfile>;

let avengers: Heroes = {
  thor: {
    skill: "shield",
    age: 100,
  },
  hulk: {
    skill: "hammer",
    age: 3000,
  },
  capt: {
    skill: "shouting",
    age: 47,
  },
};
type PhoneBook = Record<string, string>;
let familyPhones: PhoneBook = {
  dad: "010-1111-1111",
  mom: "010-2222-2222",
};

Record<객체속성 키로 사용할 타입, 객체 속성의 값으로 사용할 타입>

10. 맵드 타입 (mapped type)

  • 맵드 타입은 이미 정의된 타입을 가지고 새로운 타입을 생성할 때 사용하는 타입 문법
  • 맵드 타입을 이용하면 문자열 유니언 타입을 이용하여 객체 형태의 타입으로 변화할 수 있을 뿐만 아니라, 객체 형태의 타입에서 일부 타입 정의만 변경한 새로운 객체 타입을 정의할 수 있음
  • 객체 속성의 이름(key)은 문자, 숫자 등으로 선언할 수 있고, boolean 타입으로는 선언할 수 없음

10-1. in

type HeroNames = "thor" | "hulk" | "capt";
type HeroAttendance = {
  [Name in HeroNames]: boolean;
};

10-2. keyof

interface Hero {
  name: string;
  skill: string;
}

type HeroPropCheck1 = {
  [H in keyof Hero]: boolean;
};
type HeroPropCheck2 = {
  [H in "name" | "skill"]: boolean;
};

10-3. 매핑 수정자 (mapping modifier)

  • 매핑 수정자는 맵드 타입으로 타입을 변환할 때 속성 성질을 변환활 수 있도록 도와주는 문법

    +, -. ?, readonly

type Hero = {
  name: string;
  skill: string;
};

type HeroOptional = {
  [H in keyof Hero]?: string;
};

type HeroRequired<T> = {
  [Property in keyof T]-?: T[Property];
};

let capt: HeroRequired<HeroOptional> = {
  name: "captain",
  skill: "throwing shield",
};

10-4. 맵드 타입으로 직접 유틸리티 타입 만들기

  • Partial 타입 만들어보기
interface Todo {
  id: string;
  title: string;
}

type MyPartial = {
  [Property in keyof Todo]?: Todo[Property];
};

// 제네릭으로 넘겨받은 타입의 속성을 모두 옵션 속성으로 변환
type MyPartialV2<Type> = {
  [Property in keyof Type]?: Type[Property];
};

type TodoPartial = MyPartialV2<Todo>;

7. 기타

매개변수 vs. 인자

  • 매개변수 (parameter)
    • 함수를 정의할 때 사용되는 변수
  • 인자 (argument)
    • 함수를 호출할 때 전달되는 값

실전 프로젝트 환경 구성

1. 타입스크립트 설정 파일

// tsconfig.json
{
	"compilerOptions": {
    	"target": "es5"
    }
}
  • 타입스크립트 설정 파일은 해당 타입스크립트 프로젝트가 어떻게 컴파일될지 세부적인 옵션을 정의하는 파일
  • 예를 들어 컴파일할 대상 파일이나 폴더, any 타입의 사용 여부, 모듈 형태, 컴파일 결과물의 위치 등 다양한 옵션을 정의할 수 있음
  • 타입스크립트 설정 파일은 타입스크립트 프로젝트의 루트 레벨에 위치해야 하며 JSON 파일 형식으로 작성함
  • 타입스크립트 설정 파일은 tsc라는 타입스크립트 컴파일 명령어를 실행할 때 자동으로 인식됨
  • 설정 파일을 생성하지 않고 명령어 옵션을 줄수도 있으나 불편함
    • index.ts 파일을 컴파일할 때 타입 에러가 발생하면 컴파일 결과물을 생성하지 말라는 명령어
    • 명령어에 옵션 주는 방법
      tsc index.ts --noEmitOnError
    • 타입스크립트 설정파일에 명시하는 방법
    // tsconfig.json
    {
    	"complierOptions": {
      	"noEmitOnError": true
      },
      "files": ["index.ts"]
    }
    		npx typescript index.ts --noEmitOnError

2. 타입스크립트 설정 파일 생성

  • 방법2
    yarn add typescript
    tsc --init
  • 방법1
    npx typescript tsc --init

npx (Node Package eXecute)

  • NPM 패키지를 설치하지 않고도 실행할 수 있게 하는 도구
  • 타입스크립트 설정파일에서 자주쓰는 옵션들
    • 루트 옵션: files, extends, compilerOptions, include 등
    • 컴파일러 옵션: target, lib, module, strict, noEmitOnError 등

3. 타입스크립트 설정 파일의 루트 옵션

  • 루트 옵션은 컴파일할 대상 파일이나 폴더를 지정하는 등 프로젝트 전반적인 호나경 구성과 관련된 옵션

1) files

  • 타입스크립트 컴파일 대상 파일의 목록
  • tsc 명령어를 입력했을 때 대상이 되는 파일 목록을 다음과 같이 지정할 수 있음
// tsconfig.json
{
	"files": ["index.ts", "main.ts", "utils.ts"]
}
  • 실무 프로젝트일 경우 파일 개수가 많기 때문에 이렇게 일일이 목록을 지정하는 것 보다 include 속성을 이용하여 특정 위치나 파일 패턴으로 컴파일 대상을 지정하는 것이 효율적

2) include

  • 타입스크립트 컴파일 대상 파일의 패턴을 지정한는 속성
  • files 속성과는 다르게 다음과 같이 특정 폴더 위치나 파일 확장자를 기준으로 정할 수 있음
// tsconfig.json
// src 폴더 아래에 있는 모든 파일과 tests 폴더 아래 spec.ts 확장자를 가진 모든 파일을 컴파일 대상으로 지정하겠다는 의미
{
	"include": ["src/*", "tests/*.spec.ts"]
}

와일드 카드(*)

  • 프로그램에서 흔히 쓰는 검색 패턴
  • * : 디렉터리 구분자를 제외한 모든 파일 이름
  • **/ : 해당 폴더의 모든 하위 폴더
// tsconfig.json
// src 폴더 아래에 있는 모든 파일(하위 폴더의 파일까지 모두 포함)과 utils 폴더 바로 아래에 있는 모든 파일을 의미
{
	"include": ["src/**/*", "utils/*"]
}
  • include가 별도로 없으면 아래와 같은 의미
// tsconfig.json
{
	"include": ["**/*"]
}

3) exclude

  • 타입스크립트 컴파일을 위해 include 속성에 정의된 파일들을 검색할 때 컴파일에서 배제할 파일 목록을 정의할 수 있음
  • 주의할 점은 include 속성이 명시되었다면 include에 포함된 파일만 배제! (include는 사용하지않으면 모든 파일을 include함)
// tsconfig.json
{
  	"exclude": ["node_modules", "tests/**/*"]
}

4) extends

  • 설정 파일을 공통으로 사용하거나 빌드용 타입스크립트 설정을 분리하고 싶을 때 사용

  • 상대 경로로 지정하여 설정 파일을 불러올 수 있음

  • 예시) base.json 파일에 기본적인 컴파일러 옵션들을 정의해두고 tsconfig.json 파일에서 extends 속성으로 상속 받음

// base.json
{
	"compilerOptions": {
      "target": "es5",
      "lib": ["dom", "esnext"]
    }
}

// tsconfig.json
{
	"extends": "./base",
  	"compilerOptions": {
    	"strict": true
    }
}

프레임워크, 라이브버리 별 공통 설정 파일

4. 타입스크립트 설정 파일의 컴파일러 옵션

  • 컴파일러 옵션은 타입스크립트 컴파일 작업을 진행할 때 타입 검사 레벨, 타입 라이브러리, 모듈 등 세부적인 내용을 정의할 수 있음
  • https://www.typescriptlang.org/tsconfig

1) target

  • target 속성은 타입스크립트 컴파일 결과물이 어떤 자바스크립트 문법으로 변환될지 정의하는 옵션
  • 옵션에는 1999년 자바스크립트 스펙인 ES3(ECMAScript 3)부터 최신 자바스크립트 문법을 의미하는 ESNext까지 있음

2) lib

  • lib 속성은 브라우저 DOM API나 자바스크립트 내장 API를 위해 선언해 놓은 타입 선언 파일을 의미
  • 자바스크립트 내장 API는 Math, Promise, Set 등 자바스크립트 문법으로 지원되는 API를 의미
  • 예시
// tsconfig.json
{
	"compilerOptions": {
    	"lib": ["DOM", "ESNext"]
    }
}

// main.ts
document.querySelector("#app");

3) strict

  • strict 속성은 타입스크립트의 타입 체크 수준을 정의할 수 있는 옵션
  • true를 설정하면, 아래와 같이 여러 개의 컴파일러 옵션 속성(strict mode family)을 정의한 것과 효과가 같음
{
	"compilerOptions": {
      "strict": true,
      // strict가 true이면 아래의 속성 목록을 모두 켠 것과 같음
      
      "noImplicitAny": true,
      "noImplicitThis": true,
      "strictNullChecks": true,
      "strictBindCallApply": true,
      "strictFunctionTypes": true,
      "strictPropertyInitialization": true,
      "alwaysStrict": true,
      "useUnknownInCatchVariables": true
    }
}
  • strict 관련 속성 목록은 추후에 타입스크립트 라이브러리 버전이 올라감에 따라 추가되거나 변경될 수 있음
  • strict mode family (strict 관련 속성)
    • noImplicitAny
      • 타입 정의가 안 된 코드에서 경고를 표시하는 옵션
    • noImplicitThis
      • this 타입이 암묵적으로 any 타입을 가리키면 에러를 표시하는 옵션
    • strictNullChecks
      • null과 undefined 값이 모두 타입으로 취급되도록 타입 검사 수준을 높이는 옵션
    • strictBindCallApply
      • 자바스크립트의 call(), bind(), apply() API를 사용할 때 인자 타입이 적절한지 검사하는 옵션
    • strictFunctionTypes
      • 함수의 파라마터 타입으 ㄹ업격하게 검사하는 옵션
    • strictPropertyInitialization
      • 클래스 안에서 속성 타입이 정의되고 생성자에게 초기화까지 되어 있는 지 검사하는 옵션
    • alwaysStrict
      • use strict 모드로 파일을 컴파일하고, 컴파일한 파일 위에 'use strict' 코드를 추가하는 옵션
    • useUnknownInCatchVariables
      • try catch 구문에서 catch의 err 파라미터 타입을 unknown으로 변환해주는 옵션

4) noImplicitAny

  • 특정 코드의 타입이 정해져 있지 않은 경우 any 타입으로라도 타입 표기를 하는 옵션
  • 타입스크립트는 특정 변수나 함수의 파라미터 등 타입이 정의되어 있지 않으면 암묵적으로 any 타입으로 추론됨
  • noImplicitAny 옵션이 켜져 있으면 타입이 암묵적으로 any로 추론되게 하지 말고 명시적으로 any 타입이라고 표기해 주어야함

5) strictNullChecks

  • null 값과 undefined 값을 각각의 타입으로 인식하게 하는 옵션
  • null과 undefined는 자바스크립트를 처음 배울 때 헷갈리기 쉬운 주요 데이터 타입(원시타입)
  • null 값은 자바스크립트에서 typeof 연산자를 사용하면 object로 취급되어 더 혼란스러움
typeof null; 		// 'object'
typeof undefined;	// 'undefined'
  • strictNullChecks 옵션은 특정 연산이나 API 호출의 결과로 null 타입이나 undefined 값이 나올 수 있으니 해당 값을 주의해서 취급하라는 의미

6) allowJs

  • 타입스크립트 프로젝트에서 자바스크립트 파일도 함께 사용하고 싶을 때 추가하는 옵션
  • allowJS는 기본적으로 꺼져 있지만 true 값으로 변경하여 옵션을 켜면 타입스크립트 컴파일 대상에 자바스크립트 파일로 포함됨
  • 타입스크립트 파일에서 자바스크립트 파일을 가져올(import) 수 있게되는 것

7) sourceMap

  • 소스맵이란 타입스크립트뿐만 아니라 프론트엔드 빌드 도구에서 흔하게 사용되는 기능으로써 디버깅을 편하게 하는 역할을 함
  • 타입스크립트로 빌드(컴파일)하면 자바스크립트 파일이 생성됨. 이때 자바스크립트 파일에서 실행 에러가 발생하면 자바스크립트 코드 위치를 가리키게 됨. 컴파일된 자바스크립트 파일은 이미 원본 파일인 타입스크립트 파일과 다른 파일임. 따라서 자바스크립트 파일에서 특정 에러가 타입스크립트의 어느 코드와 연관있는지 알기 어려움
  • 소스맵은 컴파일 결과물인 자바스크립트 파일에서 에러가 발생했을 때 해당 에러가 원본 파일의 몇 번째 줄인지 가리켜 줌

8) jsx (Javascript Syntax eXtension)

  • 프론트엔드 화면 라이브러리인 react와 관련 있음
  • 타입스크립트 파일에서 작성된 jsx 문법이 자바스크립트 파일에서 어떻게 변환될지 결정할 수 있음
  • 자바스크립트 파일 안에서도 HTML과 CSS를 입력할 수 있는 문법
function App() {
	return <div>Hello React</div>
}
  • jsx 속성에 들어갈 수 있는 옵션 5가지
    • preserve
      • jsx 코드를 별도의 API로 변환하지 않고 최신 자바스크립트 문법과 라이브러리만 추가해줌
    import React from 'react';
    export const App = () => <div>Hello React</div>
    • react
      • jsx 코드를 React.createElement() 문법으로 변환해줌
    import React from 'react';
    export const App = () => React.createElement("div", null, "Hello React");
    • react-jsx
      • jsx 코드를 다음과 같이 변환해줌
    import {jsx as _jsx} from "react/jsx-runtime";
    import React from 'react';
    export const App = () => _jsx("div", {children: "Hello React"});
    • react-jsxdev
      • jsx 코드를 다음과 같이 변환해줌
    import {jsxDev as _jsxDev} from "react/jsx-dev-runtime";
    const _jsxFileName = "/home/runner/work/TypeScript-Website/TypeScript-Website/index.tsx"
    import React from 'react';
    export const App = () => _jsxDev("div", {children: "Hello React"}, void 0, false, {filename: _jsxFileName, lineNumber: 9, columnNumber: 32}, this);
    • react-native
      • preserve 옵션과 동일하게 변환해줌
    import React from 'react';
    export const App = () => <div>Hello React</div>

9) baseUrl

  • baseUrl 속성ㅇ느 프로젝트의 모듈 해석 기준 경로를 정하는 옵션
  • 이 속성은 비주얼 스튜디오 코드나 웹 스톰 등 개발 툴에서 파일 자동 완성을 올바르게 지원받는 것과도 연관이 있음
// tsconfig.json
{
	"compilerOptions": {
    	"baseUrl": "./src"
    }
}

10) paths

  • 특정 모듈을 임프토할 때 어디서 가져올지 경로를 지정할 수 있는 옵션
  • 상대 경로가 길어질 때 이를 줄이는 데 사용하는 속성으로 baseUrl 속성 값에 영향을 받음
// tsconfig.json
{
	"compilerOptions": {
    	"baseUrl": "./src",
      	"paths": {
        	"api": ["api/*"]
        }
    }
}
// LoginInfo.vue
import { fetchUser } from 'api/users';
  • path 속성을 이용하면 임포트 구문의 파일 경로를 줄일 수 있음

11) removeComments

  • 타입스크립트 컴파일을 할 때 주석을 제거해 주는 옵션
  • 기본값은 false
// tsconfig.json
{
	"compilerOptions": {
    	"removeComments": false
    }
}

5. 타입스크립트 설정 파일과 빌드 도구

  • 타입스크립트를 사용하는 대부분의 프로젝트는 웹팩 또는 롤업이라는 빌드 도구를 사용함
  • 타입스크립트는 패키지 관리 도구인 NPM으로 설치하고 빌드(컴파일)하는 과정이 필요하기 때문
  • 실무 프로젝트에서는 단순히 타입스크립트만 빌드하지 않고 다음 과정을 모두 하나의 빌드 과정에 포함시키고는 함
    • 파일 변환
      : ts 파일을 js 파일로 변환하거나, 최신 js 문법을 예전 js 문법으로 변환하거나 scss 파일을 css 파일로 변환하는 등 빌드 작업을 의미
    • 파일 압축
      : 페이지 로딩 속도를 높이려고 파일을 압축하여 용량을 줄임
    • 파일 병합
      : 여러 개의 파일을 하나의 파일로 병합하여 네트워크 요청 시간을 줄임

웹팩이란?

  • https://webpack.kr/
  • 웹팩은 모듈 번들러(module bundler)이자 개발 빌드 도구
  • 파일 여러 개와 모듈을 다루는 실무 프로젝트에서 거의 필수로 사용하는 도구
  • 모듈 번들러는 여러 개의 모듈을 하나의 모듈로 병합해 준다는 의미
  • 웹 애플리케이션을 구성하는 리소스를 웹팩으로 빌드하면 정적 자원이 나온다는 의미
  • 여러 개의 파일을 하나로 병합하고 웹 서버에 바로 올려서 사용자가들이 접근할 수 있는 형태의 파일로 변환해준다는 것
  • https://joshua1988.github.io/webpack-guide/

웹팩에 타입스크립트 설정하기

// webpack.config.js
const path = require("path");

module.exports = {
	entry: './src/index.ts',
  	module: {
    	rules: [
          {
          	test: /\.test?$/,
            use: 'ts-loader',
            exclude: /node_modules/,
          }
        ],
    },
  	resolve: {
    	extensions: ['.tsx', '.ts', '.js'],
    },
  	output: {
    	filename: 'bundle.js',
      	path: path.resolve(__dirname, 'dist'),
    },
}
  • 리액트나 뷰 같은 프론트엔드 개발 프레임워크를 사용하면 직접 작성할 필요가 없음. 프로젝트 생성 도구로 프로젝트를 생성했을 때 내부에 이미 다 정의되어 있기 때문
  • 'entry' 속성
    • 웹팩의 진입점을 의미
    • 웹팩 빌드 명령어를 실행했을 때 대상이 되는 파일의 경로를 지정
  • 'module' 속성
    • 웹팩의 로더(loader)를 의미
    • 자바스크립트 파일을 제외한 css, jpg, ttf 파일들을 모듈로 취급하려면 로덜르 설정해주어야 함
    • 타입스크립트 파일 역시 자바스크립트 파일이 아니기 때문에 ts-loader를 설정해줌
  • 'resolve' 속성
    • 웹팩의 모듈 해석 방식을 정의
    • extensions에 적힌 파일 확장자는 import 구문을 사용할 때 파일 확장자를 적지 않아도 인식하겠다는 의미
  • 'output' 속성
    • 웹팩으로 빌드된 결과물에 대한 설정
    • 위의 예시는 빌드한 파일 이름은 bundle.js고, 빌드된 파일 경로를 dist 폴더 아래라는 의미

6. 타입 선언 파일

  • 타입 선언 파일은 d.ts 확장자를 갖는 타입스크립트 파일을 의미
  • 프로젝트에서 자주 사용되는 공통 타입이나 프로젝트 전반에 걸쳐 사용하는 라이브러리 타입을 정의하는 공간

타입 선언 파일 사용 방법

  • 프로젝트 루트 레벨에 정의해 놓으면 자동으로 프로젝트 내 타입스크립트 파일에서 해당 타입을 인식

타입 선언 파일을 언제 사용해야 하는가?

  • 타입 선언 파일을 사용하면 타입스크립트 파일에 타입 코드를 작성하지 않고 다른 파일에 분리해 놓을 수 있는 이점이 있음

7. 외부 라이브러리의 타입 선언과 활용

외부 라이브러리를 사용하는 방법

  • NPM 명령어로 설치한 외부 라이브러리는 node_modules 폴더 설치됨

외부 라이브러리의 타입 선언 파일: Definitely Typed

  • 라이브러리 사용자들이 특정 라이브러리에 대한 타입을 정의해서 Definitely Typed라는 깃헙 레포지터리를 공유해둠
  • https://github.com/DefinitelyTyped
  • 해당 라이브러리의 타입 선언 파일이 있는 지 확인하려면 NPM 패키지 검색창에 @types/라이브러리명라고 입력
  • 외부 라이브러리의 타입 선언 파일은 NPM 공식 사이트에서 패키지를 검색하여 타입 선언 파일을 지원하는지 확인하고, '@types/라이브러리이름'으로 패키지가 있는지 확인한 후 프로젝트에 설치해서 사용하면 됨

외부 라이브러리에 내장된 타입 선언 파일

  • 외부 라이브러리 자체적으로 타입 정의가 되어 있기도 함

외부 라이브러리에 타입 선언 파일이 지원되지 않는 경우

  1. 직접 타입을 정의하는 방법
  • 프로젝트에 global.d.ts와 같은 선언 파일을 생성해서 필요한 부분만 타입을 임의로 정의
  1. 명령어로 타입 선언 파일 생성하기
  • 타입 선언 파일을 생성해 주는 명령어를 활용

  • 이 명령어는 대상 라이브러리의 규모가 작고 간단할 때 사용하면 좋음

    		npx -p typescript tsc <대상 파일명> --declaration --allows --emitDeclarationOnly --outDir types

Reference

profile
#의식의흐름 #순간순간 #생각의스냅샷

0개의 댓글