4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TypescriptでJavascriptライブラリーを使う方法

Posted at

####Typescriptはnode_modulesを見てるか?
結論:見てるとき、見てないときがあります。

"moduleResolution":

'node' (Node.js) か 'classic'の値を取ることができます。

import axios from 'axios';

"moduleResolution": "node"にしておくと、↑のように、
相対パスではない書き方でインポートしたときに、node_modulesを見に行きます。

"moduleResolution": "classic"にしておくと、カレントディレクトリにaxiosないかなー、
と見に行くだけになります。

####Webpackはnode_modulesを見てるか?
見てます。

node_modulesの中にあるaxiosの中の、d.tsファイルを見にいきます。

#.d.ts
d = declarations = 宣言

この拡張子のファイルを、型定義ファイルと言ったりします。

型の情報のみがザーッと入っています。

↓としておくと、勝手にdeclarationsファイルが作られます。

tsconfig.json
"declaration": true

型定義ファイル(.d.tsファイルが存在しない場合も高確率であります。)

#DefinitelyTyped
TypeScript 用の型定義リポジトリです。

昨今、特にフロントエンドでは TypeScript を使うのが当たり前となったが、
まだまだ過去の遺産、型定義すらない JavaScript ライブラリも多いのです。
型定義がなければ自前で書く必要があります。

「型定義を書く」とは、基本的に公式ドキュメントを TypeScript に変換することです。

#####@typesパッケージをインストールして、既存の型定義ファイルを使う方法

↓のようにimportしようとしたが、
node_modules/lodash/にd.tsファイル(Typescriptファイル)がなかった場合、

import _ from 'lodash';

まず模索すべきは、「誰かがこの型定義ファイルをすでに作っていないか?」です。

Typescriptは、node_modules/lodash/の次に、node_modules/@typesを見にいきます。
なので、仮にlodashの型定義ファイルが存在すれば、
インストールしてnode_modules/@types/に入れてあげれば良いのです。

googleで@types/lodashのような結果があれば、大体あります。
Image from Gyazo

↓のようなコマンドで入れてあげます。

 % npm install --save-dev @types/lodash

TypescriptでJavascriptライブラリーを使いたいときは、
まず、それのTypescript型定義ファイルが、
パッケージ(node_modules/それの名前/d.ts)にあるかどうかを確認して、
なかったらnode_modules/@typesに入れるものをgoogleで探す。

#型定義ファイルを作る方法

それでもなかったら、直接型定義ファイルを書くしかありません。

library.ts
import _ from 'lodash';

↓declare module 'lodash' { }で、lodashの型を指定することができます。

lodash.d.ts
declare module 'lodash' {
  export function shuffle<T>(arr:  T[]): T[]
}

↑これでlodashは、importされたら、shuffleというメソッドがあって、
(arr: T[ ]): T[ ]という型だよ。とTypescriptに伝えることができます。

#CDNで型定義ファイルを読み込む
これまでは、npm経由で型定義ファイルを読み込んでいました。
次に、CDN経由で、scriptから読み込む方法を見ていきます。

↓Lodash公式ページからCDN copiesをクリックして、先頭のHTMLをコピーして貼り付けます。

index.html
  <link rel="stylesheet" href="style.css">

  //↓これ
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
 
  <script src="dist/bundle.js" defer></script>

↓その後、型を指定してあげるとエラーが消えます。

tslodash.ts
declare module 'lodash' {
  export function shuffle<T>(arr:  T[]): T[]
}

interface Lodash {
  shuffle<T>(arr:  T[]): T[]
}

declare const _: Lodash

#namespace
名前空間です。名前の衝突を防ぐ役割があります。
しかし、import, exportを優先するように言われており、あまり使う機会はありません。

↓{  }内のnameを外で使えます。

library.ts
namespace myApp {
  const hello = 'hello in namespace';
  export const name = 'Quill';
}

const hello = myApp.name

↓namespaceで型を定義する方法

library.ts
namespace myApp {
  const hello = 'hello in namespace';
  export const name = 'Quill';
  export interface Nameable {
    name: string;
  }
}

let nameable: myApp.Nameable;

〜.〜のような型があれば、基本的にはnamespaceが使われていると思ってください。

#declear
「どこかでその変数が使われてるよ」という意味です。
↓constと書いてありますが、実際にメモリを用意して変数を作ってるわけではなく、
↓どこかで使われているよ。というのをお知らせしてるだけです。

axios/index.ts
declare const axios: AxiosStatic;

export default axios;

ambient declaration(アンビエント宣言)と呼ばれたりします。

ambient = 周囲、環境

#lodashの型定義ファイルの中身を見てみる

↓「トリプルスラッシュディレクティブ」
↓ ts → jsに変換したときに無くなります。

lodash/index.ts
/// <reference path="./common/common.d.ts" />

↓node.js用のexport文。

lodash/index.ts
export = _;

↓importを使わずに、直接読み込みなどをしたときに、_を使えるようにするための決まり文句。

lodash/index.ts
export as namespace _;

####declare global { }

declare global { }の中は、
全部自動的にアンビエント宣言になり、かつグローバルで使えるようになります。

#同じ名前の値・型・namespace
Typescriptの概念では、主にデータの種類が3種類あります。
それが「値・型・namespace」です。
↓さらに、それら3つは共存することもできます。

library.ts
let name: string;
interface name {}
namespace name{}

値同士・型同士はダメです。

#####例外

↓interface同士は共存できます。

library.ts
interface name {
  first: string
}
interface name {
  second: number
}

↓classとinterfaceも共存できます。

library.ts
class name {}
interface name {
  first: string
}
interface name {
  second: number
}

classは、interfaceも定義していると考えられます。
classが定義する型が、interfaceのような扱いを受けるからです。

↓namespace同士も共存できます。

library.ts
namespace name{
  const first: string = 'Peter';
}
namespace name{
  const first: string = 'Peter';
}

mergeされて1つになるイメージです。

同名のプロパティは、型が違うとエラーになります。
同名のメソッドはオーバーロードされます。

・値を含んだnamespaceと変数はダメです。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?