📦

frourio の Methods を型安全に定義する

2021/09/23に公開
1

2022/05/21追記

aspidaのv1.10.0で記事中のDefineMethodsが追加されました🎉
https://github.com/aspida/aspida/releases/tag/v1.10.0

そのためこちらの記事で紹介したワークアラウンドは必要なくなりました。

こちらのPRで実装していただけたようです。
https://github.com/aspida/aspida/pull/687

PR中でもこの記事の言及があり、記事を書くことで新機能のキッカケになれたようで嬉しいです。

---追記終わり

三行まとめ

  • npm i aspida
  • type DefineMethods<T extends AspidaMethods> = T;を定義
  • DefineMethodsでより型安全な世界

frourio はとっても型安全

frourio は Methods として API の型を一つだけ定義すればフロントエンド、バックエンド間の疎通を TypeScript で静的に検査できるフルスタックフレームワークです。

例えば、

index.ts
export type Methods = {
  get: {
    resBody: string
  }
}

このように Methods型 に、 http メソッドごとにリクエストボディーの型やレスポンスの型を定義すると、フロントエンド、バックエンドで共通していい感じに型検査ができます。

型を一箇所変更するだけですべてチェックしてくれるのはとても便利で安心ですね。

Methods を定義する時は補完が効かない

一気通貫の型検査によって安全なのはもちろん、補完がもろもろ効いてくれるのがありがたいです。ただ、全てのベースとなる Methods型 を定義する時には残念ながら補完が効きません。

例えば、

と入力した段階でgetpostなど使用できるメソッドの補完が出てほしいなーと欲がでます。

また、

index.ts
export type Methods = {
  gets: { // 👈 gets!!
    resBody: string
  }
}

のようにメソッドのプロパティを間違えてしまっても、エディタ上では教えてくれません。(frourio が型を自動生成する段階でエラーは出してくれます。)

Methods を型安全に(補完を効かせながら)定義する

なんとか補完を効かせながらMethods型を定義できないでしょうか?

ところで frourio の内部では同じ作者様の aspida というライブラリが使われ、こちらの仕組みで型が生成されています。

内部を見てみるとMethods型の型も aspida にAspidaMethodsとして定義されていました。詳細は省略しますが、こんな感じの型です。

export declare type LowerHttpMethod =
  | 'get'
  | 'post'
  | 'put'
  | 'delete'
  | 'head'
  | 'patch'
  | 'options';

export declare type AspidaMethodParams = // ...

export declare type AspidaMethods = {
  [method in LowerHttpMethod]?: AspidaMethodParams;
};

こちらを利用してみましょう。

型アサーション

まず型アサーションで試してみると?

export type Methods = {

} as AspidaMethods // ❗️エラー

型を定義する時点では as での型アサーションを使用することはできず、エラーになってしまいます。

DefineMethods 型を定義する

そこでAspidaMethodsをラップしたDefineMethods型を作ってみます。

type DefineMethods<T extends AspidaMethods> = T;

これでDefineMethods型を使うことでいい感じに補完が効くようになりました!

type Methods = DefineMethods<{
  get: // ...
}>


まとめ

frourio でより型安全で、補完が効く環境が作れました。frourio を始めようと思うと、最初に Methods を定義する時に補完が効かず、補完に慣らされまくった身にはちょっとしたハードルだったんですが、これでより気軽に開発に取りかかれそうです。

Discussion