typescriptでJavaScriptライブラリを使う方法

今回はtypescriptでjavascriptライブラリを使う方法について紹介します。

**※前提として、webpackを使用しているものとします。**

今回使用するライブラリは**axius**です。

axiosの詳細については[こちら](https://qiita.com/Ryusou/items/8b7d239819e3a3874638)の記事が非常に参考になります。


<h2>1.ライブラリのインストール

下記のコマンドでライブラリをインストールします。

`npm install axios`

<h2>2.ライブラリを使っていく

今回はlibrary.tsを新規作成し記述していきます。

```ruby:library.ts
import axios from 'axios';
```
上記のように記述することでimportできます。

しかし、このままだとエラーが出てしまいます。

なぜエラーが出るかというと、

そもそも、ここで書いたimportはどこから読み込むのでしょうか。
<img width="603" alt="スクリーンショット 2020-07-08 12.29.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472442/6592869c-31f4-b770-7455-6b25781c8a64.png">
node_modulesディレクトリの中のaxiosを読み込みます。

解決方法を解説します。

tsconfig.jsonの中の "moduleResolution": "node",のコメントアウトをなくします。

こちらです。

```ruby:tsconfig.json
 "moduleResolution": "node",
```
これで正しく読み込むことができます。

では、moduleResolutionとはなんでしょうか。

簡単に説明すると、moduleResolutionをnodeとしておくと、

moduleをインポートした時にnode_modulesの中を見にいくようになります。

さらに細かく説明すると、

typescriptで使う際には、上の画像の中のindex.d.tsの中を読み込みます。
（ファイル名のdはデクラレーションを意味します）
<img width="568" alt="スクリーンショット 2020-07-08 13.08.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472442/5689b4df-77c0-226c-2fdd-a3da3df69159.png">

中身を見てみましょう。

```ruby:index.d.ts
export interface AxiosTransformer {
  (data: any, headers?: any): any;
}

export interface AxiosAdapter {
  (config: AxiosRequestConfig): AxiosPromise<any>;
}

export interface AxiosBasicCredentials {
  username: string;
  password: string;
}

export interface AxiosProxyConfig {
  host: string;
  port: number;
  auth?: {
    username: string;
    password:string;
  };
  protocol?: string;
}

export type Method =
  | 'get' | 'GET'
  | 'delete' | 'DELETE'
  | 'head' | 'HEAD'
  | 'options' | 'OPTIONS'
  | 'post' | 'POST'
  | 'put' | 'PUT'
  | 'patch' | 'PATCH'
  | 'link' | 'LINK'
  | 'unlink' | 'UNLINK'

export type ResponseType = 
  | 'arraybuffer' 
  | 'blob' 
  | 'document' 
  | 'json' 
  | 'text' 
  | 'stream'

export interface AxiosRequestConfig {
  url?: string;
  method?: Method;
  baseURL?: string;
  transformRequest?: AxiosTransformer | AxiosTransformer[];
  transformResponse?: AxiosTransformer | AxiosTransformer[];
  headers?: any;
  params?: any;
  paramsSerializer?: (params: any) => string;
  data?: any;
  timeout?: number;
  timeoutErrorMessage?: string;
  withCredentials?: boolean;
  adapter?: AxiosAdapter;
  auth?: AxiosBasicCredentials;
  responseType?: ResponseType;
  xsrfCookieName?: string;
  xsrfHeaderName?: string;
  onUploadProgress?: (progressEvent: any) => void;
  onDownloadProgress?: (progressEvent: any) => void;
  maxContentLength?: number;
  validateStatus?: (status: number) => boolean;
  maxRedirects?: number;
  socketPath?: string | null;
  httpAgent?: any;
  httpsAgent?: any;
  proxy?: AxiosProxyConfig | false;
  cancelToken?: CancelToken;
}

export interface AxiosResponse<T = any>  {
  data: T;
  status: number;
  statusText: string;
  headers: any;
  config: AxiosRequestConfig;
  request?: any;
}

export interface AxiosError<T = any> extends Error {
  config: AxiosRequestConfig;
  code?: string;
  request?: any;
  response?: AxiosResponse<T>;
  isAxiosError: boolean;
  toJSON: () => object;
}

export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {
}

export interface CancelStatic {
  new (message?: string): Cancel;
}

export interface Cancel {
  message: string;
}

export interface Canceler {
  (message?: string): void;
}

export interface CancelTokenStatic {
  new (executor: (cancel: Canceler) => void): CancelToken;
  source(): CancelTokenSource;
}

export interface CancelToken {
  promise: Promise<Cancel>;
  reason?: Cancel;
  throwIfRequested(): void;
}

export interface CancelTokenSource {
  token: CancelToken;
  cancel: Canceler;
}

export interface AxiosInterceptorManager<V> {
  use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: any) => any): number;
  eject(id: number): void;
}

export interface AxiosInstance {
  (config: AxiosRequestConfig): AxiosPromise;
  (url: string, config?: AxiosRequestConfig): AxiosPromise;
  defaults: AxiosRequestConfig;
  interceptors: {
    request: AxiosInterceptorManager<AxiosRequestConfig>;
    response: AxiosInterceptorManager<AxiosResponse>;
  };
  getUri(config?: AxiosRequestConfig): string;
  request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>;
  get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
  delete<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
  head<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
  options<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
  post<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
  put<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
  patch<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
}

export interface AxiosStatic extends AxiosInstance {
  create(config?: AxiosRequestConfig): AxiosInstance;
  Cancel: CancelStatic;
  CancelToken: CancelTokenStatic;
  isCancel(value: any): boolean;
  all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
  spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
}

declare const Axios: AxiosStatic;

export default Axios;
```
この中にtypescriptの型情報などが入っており、このファイルを型定義ファイルを呼びます。

これのおかげでtypescriptでも使えるようなっています。

しかし、全てのサードパッケージ製パッケージにデクラレーションファイルがあるとは限らず、ある方が少ないので注意が必要です。

ない場合にどうすれば良いかを次の記事で解説します。