1
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 1 year has passed since last update.

しょーもない記事ばかりすみません。記憶力低下とノウハウ散逸の対策でここに全部書くって決めたんです……。

目的

TypeScript で、 JSON 形式の手作り設定ファイルを読み込むと何もかも any で気持ち悪いので インターフェースを定義して as してみる→

  • キーがサジェストされる(インテリセンス)ようになる
  • 値の型が決まる

でも、ほんとうに値が入っていて望みの型になっているか分からない
→拡張で解決!

  • JSON記入時にサジェストされ、キーの不足や名前誤り、書式不正が指摘される

→バリデーションしなくてすむ!(スキーマ使ってバリデーションしろパッケージあるから)

VSCode 拡張のインストール

Typescript JSON schema generator - Visual Studio Marketplace

使用手順

  1. 設定
    settings.json に設定を追加する。

    • json.schemas
      対象ファイル(globっぽく *,**,! が使える1)とスキーマファイルの組を指定。これは拡張ではなくVSCode標準の設定。
    • generateJSONSchema.jsDoc
      extended にすると JSDoc の説明がインテリセンスに表示される。
    • generateJSONSchema.additionalProperties
      定義されてないキーを書くのを許可するかどうか。継承先の項目まであえて管理しないとか、コメント用キーを許してあげたいなど用途に応じてどうぞ。
    {
      "json.schemas": [
        {
          "fileMatch": ["config/example/*.json"],
          "url": "./config/schema/schema-example.json"
        },
      ],
      "generateJSONSchema.jsDoc": "extended",
      "generateJSONSchema.additionalProperties": true
    }
    
  2. スキーマ生成
    目的のインターフェースが書かれている .ts ファイルを開き、コマンド Generate JSON Schema for type... を実行し数秒待つ

  3. 保存
    スキーマが出力されるので、そのへんに .json ファイルとして格納する

応用

各種制約の定義

JSON Schema で使用されるキーワードを JSDocにタグ(@xxx)として記述すると、それがスキーマに書き込まれる。数値なら最大値であったり、文字列なら長さや書式(URLや日付)であったりを制限できる。ただし、 @type は使えない2

typescript-json-schema の README 引用・一部改変
export interface Shape {
    /**
     * The size of the shape.
     *
     * @minimum 0 ←最小値
     * @maximum 10 ←最大値
     * @TJS-type integer ←効きません
     */
    size: number;
}

整数の制約をつくりたい

@multipleOf 1 とすれば 1 刻みの数すなわち整数とすることができる。
いちいちJSDocを書きたくないのであれば、

/**
 * 整数
 * @multipleOf 1
 */
type integer = number;

// とか

/**
 * 自然数
 * @multipleOf 1
 * @minimum 0
 */
type natural = number;

を定義して目的のプロパティの型を integer 等に置き換えてしまえば良い3

改修時の注意

スキーマの変更は自動反映されない(場合がある?)。 VSCode を再起動するか、 json.schemasurl あたりをいじって保存すると再読込される。 JSON: Clear Schema Cache というそれっぽいコマンドがあるが、効かない。 4

  1. 説明文にはワイルドカードが使えるよ、とは書いてあるが、 glob が使えるとは書いてない。でもそうか、 glob って一言に言ってもたくさん実装があるから、使える記号が定まらないよね。

  2. @type が使えたら使えたでプログラムのほうがおかしなことになるので仕方ない。この拡張は内部で ts-json-schema-generator という npm ツールを使っており、さらにこれは typescript-json-schema という npm パッケージをもとに作られているので、細かい挙動はリンク先を参照。 type 使えない問題のワークアラウンドが本家にはあるが移植されていないので注意。

  3. 型のエイリアスを作る方法は本家でも紹介されているけど、アノテーションを使わないとうまく行かなかったので形を変えてご紹介。

  4. VSCode の GitHub で提起されたけど新機能リクエスト扱いされてた ので仕様です。

1
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
1
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?