maxfie1d のブログ

マイクロソフト系技術ネタを中心に書きます。

Todo アプリを作ることを通して、TypeScript に慣れよう

友人に TypeScript(TS) を覚えてもらうために、コンソールアプリ(黒い画面で動くやつ)で Todo アプリを作るという課題を出しました。

そこで、お手本ではないですが自分も TS で作ったので、 ポイントを解説したいと思います。

Todo アプリの仕様

アプリの仕様は大体こんな感じ。

Todo は以下のように、Todoの内容と一意な ID 番号を持っていること。

interface Todo {
    subject: string;
    id: number
}

使えるサブコマンドは addcomplete の2種類。

# Todo の一覧を表示する
# ts-todo

# Todo を追加する
$ ts-todo add [Todo の内容]

# Todo を完了済みにする
$ ts-todo complete [Todo の ID]

ポイント解説

ではポイントを解説していきます。

ソースコードここにあるので、 全体を見るにはこちらを参照。

github.com

ポイント1: 実行時引数を取得する

Node.js の API を使うことで、実行時の引数(今回はaddcomplete)を取得することができます。 TypeScript の場合は忘れずに npm install @types/node をして、型定義ファイルをインストールしておきましょう。

実行時引数はprocess.argvからアクセスすることができます。 型はstring[]で、3番目以降の要素に欲しい情報があります。 なので、

const subcommand = process.argv[2];
const arg = process.argv[3];

としてもいいのですが、ここは TS で使えるこちらの記法を使うとよりスマートでいいと思います。

const [_1, _2, subcommand, arg] = process.argv;

_1, _2は「破棄する」という意味で、無意味な名前で値を受け取っています。 ちなみに下のコードも有効、で同じことができます。

const [, , subcommand, arg] = process.argv;

ポイント2: 配列の要素に対して同じ処理を行う

特に C言語を経験している場合、for(int i = 0; i < size; i++) {} とやってしまいがちですが、 TS ではfor-ofが使えます。

以下のコードは、登録されている Todo をコンソール画面に一覧するという処理です。 for-ofを使って、それぞれのtodotoString()メソッドを呼び出しています。

export async function list(): Promise<boolean> {
    const todos = await restoreTodos();
    for (const todo of todos) {
        console.log(todo.toString());
    }
    return Promise.resolve(true);
}

for-ofを使うことで、letを使わずに済むというのもポイントです。

ポイント3: async, await, Promise

TS では普通に非同期処理が扱えます。 メソッドや関数内で非同期処理を行う(awaitキーワードを使う)場合は、 asyncキーワードを関数やメソッドの宣言の冒頭につけておきます。

export async function add(todo: string): Promise<boolean> 

また、非同期関数や非同期メソッドの返り値の型は Promise<T>になります(Tは返り値の型)。