しょーもない記事ばかりすみません。記憶力低下とノウハウ散逸の対策でここに全部書くって決めたんです……。
目的
TypeScript で、 JSON 形式の手作り設定ファイルを読み込むと何もかも any
で気持ち悪いので インターフェースを定義して as
してみる→
- キーがサジェストされる(インテリセンス)ようになる
- 値の型が決まる
でも、ほんとうに値が入っていて望みの型になっているか分からない
→拡張で解決!
- JSON記入時にサジェストされ、キーの不足や名前誤り、書式不正が指摘される
→バリデーションしなくてすむ!(スキーマ使ってバリデーションしろパッケージあるから)
VSCode 拡張のインストール
Typescript JSON schema generator - Visual Studio Marketplace
使用手順
-
設定
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 }
-
-
スキーマ生成
目的のインターフェースが書かれている.ts
ファイルを開き、コマンドGenerate JSON Schema for type...
を実行し数秒待つ -
保存
スキーマが出力されるので、そのへんに.json
ファイルとして格納する
応用
各種制約の定義
JSON Schema で使用されるキーワードを JSDocにタグ(@xxx
)として記述すると、それがスキーマに書き込まれる。数値なら最大値であったり、文字列なら長さや書式(URLや日付)であったりを制限できる。ただし、 @type
は使えない2。
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.schemas
の url
あたりをいじって保存すると再読込される。 JSON: Clear Schema Cache
というそれっぽいコマンドがあるが、効かない。 4
-
説明文にはワイルドカードが使えるよ、とは書いてあるが、 glob が使えるとは書いてない。でもそうか、 glob って一言に言ってもたくさん実装があるから、使える記号が定まらないよね。 ↩
-
@type
が使えたら使えたでプログラムのほうがおかしなことになるので仕方ない。この拡張は内部で ts-json-schema-generator という npm ツールを使っており、さらにこれは typescript-json-schema という npm パッケージをもとに作られているので、細かい挙動はリンク先を参照。type
使えない問題のワークアラウンドが本家にはあるが移植されていないので注意。 ↩ -
型のエイリアスを作る方法は本家でも紹介されているけど、アノテーションを使わないとうまく行かなかったので形を変えてご紹介。 ↩