モチベーション
REST API からのレスポンスに Flow の型が欲しい。別途 JSON Schema は定義するので、それを使って生成したい。
json-schema-to-flow-type という既存のパッケージはあるもののあまりメンテされておらず、 Babel v7 で動かなくて困ったりした。修正して Pull request してみたけど残念ながら反応が無さそう。
課題として面白そうだからちょっと作ってみようと思った。
作ったもの
Igata
https://github.com/sakai-akinobu/igata
https://www.npmjs.com/package/igata
鋳造における 鋳型 をイメージして igata というネーミングにしたが、深い意味は無い。
使い方
npm install igata
import {convert} from 'igata';
convert({$id: 'String', type: 'string'});
// => export type String = string;
convert({$id: 'Enum', enum: [1, 2]});
// => export type Enum = 1 | 2;
convert({$id: 'Object', type: 'object', properties: {foo: {type: 'string'}}});
// => export type Object = {\n foo?: string\n};
convert({$id: 'Array', type: 'array', items: {type: 'string'}});
// => export type Array = string[];
convert({$id: 'Tuple', type: 'array', items: [{type: 'string'}, {type: 'number'}]});
// => export type Tuple = [string, number];
convert({$id: 'Union', type: ['string', 'number']});
// => export type Union = string | number;
convert({$id: 'ComplexUnion', anyOf: [{type: 'number'}, {type: 'object', properties: {foo: {type: 'string'}}}]});
// => export type ComplexUnion = number | {\n foo?: string\n};
Nullable な型を表現するには type
に null
を含めるといい。
const jsonSchema = {
$id: 'Nullable',
type: ['string', 'null'],
};
convert(jsonSchema);
// => export type Nullable = string | null;
Exact object types は additionalProperties
を使って表現できる。
const jsonSchema = {
$id: 'ExactObject',
type: 'object',
additionalProperties: false,
properties: {
name: {
type: 'string',
},
},
};
convert(jsonSchema);
// => export type ExactObject = {|\n name?: string\n|};
作ってみた感想
Flow の型としては表現できない物が多々あって、例えば JSON Schema における oneOf は Flow の型としては正確に表現できない。なので、Flow の型として落とし込める物とそうでないものを取捨選択する必要が出てくるので、その判断がちょっと難しいなぁという感じ。