LoginSignup
3
1

openapi-typescript@v7(β)でreadonly修飾子が追加されるようになった

Last updated at Posted at 2023-12-01

openapi-typescript

openapi-typescriptはOpenAPI SpecからTypescriptの型を生成してくれるライブラリです.

例えば下のようなOpenAPI Specから

openapi: "3.0.3"

info:
  title: "Sample"
  version: "1.0.0"

paths:
  "/todo":
    get:
      summary: "get todo"
      responses:
        "200":
          description: "success"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Todo"
components:
  schemas:
    Todo:
      type: object
      required: ["commonProp"]
      properties:
        commonProp:
          type: string

このような型が生成できます.

export interface components {
  schemas: {
    Todo: {
      commonProp: string;
    };
  };
};

readOnly属性(OpenAPI Spec)

OpenAPIではスキーマのプロパティに対してreadOnly属性(writeOnly)を付与することができる.これにより一つのスキーマでリクエストとレスポンスで異なるスキーマを表現できる.
例えば次のようなOpenAPI Specの場合

openapi: "3.0.3"

info:
  title: "Sample"
  version: "1.0.0"

paths:
  "/todo":
    post:
      summary: "post todo"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Todo"
      responses:
        "200":
          description: "success"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Todo"
components:
  schemas:
    Todo:
      type: object
      required: ["commonProp", "readProp"]
      properties:
        commonProp:
          type: string
        readProp:
          type: string
          readOnly: true

Postのリクエストとレスポンスに同じTodoスキーマを使用しているが、生成されるドキュメントでは

  • リクエスト => {"commonProp": "string"}
  • レスポンス => {"commonProp": "string","readProp": "string"}
Redoc

image.png

といった型として表現される。

openapi-typescript@v6 の場合

先ほどのreadPropを含むOprnAPI Specから現行のopenapi-typescript(6.7.1)による型生成を行うと以下のような出力が得られる.

export interface components {
  schemas: {
    Todo: {
      commonProp: string;
      readProp: string;
    };
  };
};

OpenAPI Spec上のreadOnlyが無視された型が生成される.
もしリクエスト用の型を作りたい場合は,

type Todo = components["schemas"]["Todo"];
type TodoRequest = Omit<Todo, "readProp">;
/*
type TodoRequest = {
    commonProp: string;
}
*/

のように手動で取り除く必要があった.

  • Issueは上がっているが進展は無さそう (対応するための実装は書いてある)

openapi-typescript@v7 の場合

同様に先ほどのOpenAPI Specを openapi-typescriptの7.0.0-next.5で型生成を行うと次のような型が生成される.

export interface components {
    schemas: {
        Todo: {
            commonProp: string;
            readonly readProp: string;
        };
    };
};

このようにOpenAPI Spec上でreadOnly属性を付けたプロパティにはTypescript上でもreadonly修飾子が設定されている.

これで先ほどのTodoRequestを作成したい場合はreadonlyを取り除くようなTypeを書いて

type Todo = components["schemas"]["Todo"];
type readonlyプロパティ除外する型<T> = ... 
type TodoRequest = readonlyプロパティ除外する型<Todo>

のようにすれば良い.

まとめ

readonly がついて嬉しい!(ただし, writeOnlyは非対応)

openapi-typescript@v7ではRedoclyによるスキーマ検証や,EnumをトップレベルにUnion型として生成する等の機能が含まれています.

(参考) readonlyプロパティ除外する型

任意のobject型からreadonly修飾子のついたプロパティを除外する方法は次のような方法がある.

こちらについてはまた別の機会に記事にするかもしれません.

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