はじめに
- Validationコードを手で書きたくなかった
- JSON schemaを手書きしたくなかった(typescriptの型定義を使ってほしい)
国内外たくさんやってることだけど、真似しても使うのに時間がかかった。
最小構成のコードを書く。
まず、Validationができてない状態とは?
index.ts
interfaceCat{name:string,age:number}constcatObj=JSON.parse('{"name":"tamago", "weight":2.0}');constcat=catObjasCat;console.log(cat.age);//undefined (Catのageはオプショナルじゃないのに!)
さあ、validationしよう
- 実行前にtypescriptコードからtypescript-json-schemaでJSON schema(.json)を生成する
- 実行時にajvでJSON Schemaを読み込んで、JSONをvalidationする
1.実行前にtypescriptコードからtypescript-json-schemaでJSON schema(.json)を生成する
typescript-json-schemaをインストール
% npm install typescript-json-schema -g
typescriptコードからJSON schemaを生成
型情報が含まれるtypescriptファイル
cat.ts
interfaceCat{name:string,age:number}export{Cat};
cat.tsのCat型のスキーマをCatSchema.jsonに吐き出す
(cat.tsのように単独ファイルにしていなくてもいい)
% typescript-json-schema --strictNullCheckstrue--noExtraPropstrue cat.ts Cat > CatSchema.json
--strictNullChecks Make values non-nullable by default. [boolean] [default: false]
--noExtraProps Disable additional properties in objects by default. [boolean] [default: false]
2. 実行時にajvでJSON Schemaを読み込んで、JSONをvalidationする
ajv他をインストール
% npm install ajv --save
% npm install @types/node --save-dev
% npm install @types/ajv --save-dev
コード全体
index.ts
import*asfsfrom'fs'import*asAjvfrom'ajv';import{Cat}from'./cat'constmyJSON='{"name":"tamago", "weight":2.0}'constcatObj=JSON.parse(myJSON);constajv=newAjv();constcatSchema=JSON.parse(fs.readFileSync('./CatSchema.json').toString());constvalidate=ajv.compile(catSchema);if(validate(catObj)){console.log('validation ok');//安心してasを使おうconstmyCat=catObjasCat;}else{console.log('validation ng');console.error(validate.errors);}
実行
% ts-node index.ts
validation ng
[{ keyword: 'additionalProperties',
dataPath: '',
schemaPath: '#/additionalProperties',
params: { additionalProperty: 'weight'},
message: 'should NOT have additional properties'}]
ts-node便利なのでよく使っています。
typescriptの型定義のオプショナルもちゃんと扱ってくれるようです。
まとめ
事前のJSON Schema生成はいるが、自動でvalidation環境が作れる。
丁寧な日本語メッセージを返したい場合は、ErrorObject型をアレコレしましょう。
Typescriptの標準機能で欲しい。