KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

【TypeScript】Yaml を読み込んで(無理やり)型付けする

こちらは株式会社カケハシ x TypeScriptアドベントカレンダー2021 20日目の記事です。

タイトルの通り、TypeScript ファイルに Yaml データを読み込んで型付けをする方法です。

TypeScript 環境のセットアップ

まずは TypeScript 環境をつくります。

mkdir typed-yaml-demo
cd typed-yaml-demo

npm init -y

今回は ts-node を利用。

npm install -D typescript
npm install -D ts-node
npm install -D tslib @types/node

Yaml を利用可能にする

次に、yaml を ts ファイルに import できるようにします。

今回は js-yaml を利用。さらに、型定義ファイルもインストールしておきます。

npm install --save js-yaml
npm install -D @types/js-yaml

クライアントサイドの場合は、webpack などバンドラーを設定して、yaml-loader などを使う必要があります。

Yaml データの読み込み

次に、Yaml に記述したデータを、TS ファイルに読み込みます。

適当なファイルを作成。

touch script.ts config.yaml

Yaml データを作成。設定値のようなものを記述してみました。

# config.yaml
env:
  admin: true
  port: 3000
timeout: 10_000

TS ファイルを作成。上述の Yaml データを読み込みます。

// script.ts
import { load } from 'js-yaml'
import { readFileSync } from 'fs'

const config = load(readFileSync('config.yaml', 'utf8'))

console.log(config);

package.json に実行スクリプトを追加。

// package.json
  "scripts": {
    "start": "ts-node script.ts"
  },

無事に読み込まれたことが確認できます。

npm start

> typed-yaml-demo@1.0.0 start
> ts-node script.ts

{ env: { admin: true, port: 3000 }, timeout: 10000 }

Yaml データに(無理やり)型付け

ここで、TS ファイル上の config データを見てみます。

unknown となっていますね。

型定義を追加し、アサーション利用します。

// script.ts
type Config = {
    env: {
        admin: boolean
        port: number
    },
    timeout: number
}
const config = load(readFileSync('config.yaml', 'utf8')) as Config

改めて見てみると、型がついていることが分かります。

アサーションをしているので、当たり前といえば当たり前なのですが…。要は、JS のオブジェクトとして読み込んでしまえば、型を付けられるよね、という話でした。

ジェクネクスを使うなら、以下のように書けます。

// script.ts
import {load as original} from 'js-yaml';

const load = <T = ReturnType<typeof original>>(...args: Parameters<typeof original>): T => load(...args);

type Config = {
    env: {
        admin: boolean
        port: number
    },
    timeout: number
}

const config = load<Config>(readFileSync('config.yaml', 'utf8'))

参考にした SlackOverflow 記事。