TypeScriptの基本

TypeScriptとは

JavaScriptの世界に静的型付けを持ち込んだイメージ。JavaScriptのゆるふわ感を緩和してくれる。TypeScriptでかいたソースコードコンパイラ(トランスパイラ)で変換するとJavaScriptのコードが生成されるので、そのソースコードをnode.jsなどで実行する。なお、Denoを使うとTypeScriptのソースを直接実行することができる。

以下、node.jsで触ってみる。

準備

適当なディレクトリを作ってからそのディレクトリ内に移動して、初期化。

npm init -y

-yをつけないとインタラクティブにいろいろ聞かれるが、-yをつけるとすべてデフォルト値で一気に設定ファイル(package.json)を生成してくれる。

TypeScriptのインストール

このプロジェクトにTypeScriptをインストールする。

npmでのパッケージのインストールには、

npm install パッケージ名

と入力する。installはiと一文字だけ入力することでも同じ結果になる。つまりこんな感じ。

npm i パッケージ名

また開発専用のパッケージをインストールする場合は、オプションで--save-devあるいは-Dオプションを付与する。-Dのほうを使うなら、こんな感じ。

npm i -D パッケージ名

TypeScriptは開発中しか使わないので、このオプションを付与してインストールする。

npm i -D typescript

これにより、./node_modules/.bin/tscという実行ファイルがインストールされる。たぶんTypeScript Compilerの略。

TypeScriptの設定ファイルを作る

TypeScriptの設定値はやまほどあるが、以下のコマンドで丁寧な説明がコメントで記載されている設定ファイルが生成されるので、これを編集すればよい。

./node_modules/.bin/tsc --init

コマンドを実行したディレクトリに設定ファイルであるtsconfig.jsonが生成されているはず。

例えば、こんな行がある。

    // "outDir": "./",                                   /* Specify an output folder for all emitted files. */

コメントに、出力先のフォルダを指定するんだよ的なことが書いてあるので、コメントアウトを外してからJavaScriptのコードを出力するフォルダ名を書く。

    // "outDir": "./dist",

型定義の書き方

こんな感じ。変数名のうしろにコロンを書いて、さらにその後ろに型の名前を書く。

let n: number;
let s: string;
let a1: number[]; // 配列
let t: [number, string, string]; // これはタプル

オブジェクトの場合、オブジェクトリテラルを使う。

let c: {d: number} ={
  d: 1234;
}

オブジェクトリテラルにおいて、読み取り専用の変数にはreadonly、あってもなくてもよい変数には?を付与する。

let e: {
  readonly f: string;
  g?: number;
}

エイリアスを使うとオブジェクトを生成する都度オブジェクトリテラルを書く必要がなくなり簡潔なコードにすることができる。

type A = {
  h: string;
  i: number;
}

関数での型指定

関数の引数と戻り値ならこう

function sonomamakaesu(a : number) : number {
  return a;
}

型定義同様、?を使って省略できることを示すことができる。

function f(a: number, b?: number) {
  console.log(a);
  console.log(b); // 省略された場合はundefinedと出力される
}

値を書くことで省略時のデフォルト値を指定することができる。

function f(s = "default parameter") {
  console.log(s);
}

レストパラメータを使えば可変長引数も実現できる。

function f(...nums: number[]) {
  nums.map((x: number) => {
    console.log(x);
  });
}

関数自身がどんな型なのかを指定することもできる。

function f0(a: number): number {
  return a * a;
}

function f1(f: (x: number) => number): void {  // ここの引数に注目
  console.log(f(10));
}

f1(f0);

コーディング時に型を特定できない場合はジェネリック型を使うことができる。 始まりのカッコの直前に<と>でくくって型を指し示す文字列を書いておいて、関数定義内ではその文字列を型を記すべき箇所に書いていく。

function f<T>(x: T) {
  console.log(x);
}

f(1); // 省略することもできるし、
f<string>("asdf");  // 明示することもできる。