Awaited<Type> を使って Promise の返り型を定義する
TypeScript のユーティリティ型に Awaited
内容としては、Promise
// A = string
type A = Awaited<Promise<string>>;
// B = number
type B = Awaited<Promise<Promise<number>>>;
// C = boolean | number
type C = Awaited<boolean | Promise<number>>;
また、同じくユーティリティ型の ReturnType を組み合わせると、関数の返り値の Promise の型を定義できます。以下で見ていきましょう。
個人的利用シーン
私が利用したケースとして、このブログでも使っている microcms-js-sdk の getList 関数の返り値の型を定義したかったときです。
getList は T に型を渡すと、Promise の MicroCMSListResponse T として返してくれます。
getList: <T = any>({ endpoint, queries, customRequestInit, }: GetListRequest) => Promise<MicroCMSListResponse<T>>
MicroCMSListResponse はこのような型定義になっています。getList で渡した T が、contents: (T & MicroCMSListContent)[] の定義になります。
interface MicroCMSListResponse<T> {
contents: (T & MicroCMSListContent)[];
totalCount: number;
limit: number;
offset: number;
}
上記でも述べましたが、Awaited と ReturnTypeを使うと MicroCMSListResponse の定義を取得することができます。以下一例です。
export const getPosts = async () => {
return await client.getList<PostType>({
endpoint: "posts",
});
};
// type PostsReturnType = MicroCMSListResponse<PostType>
type PostsReturnType = Awaited<ReturnType<typeof getPosts>>
MicroCMSListReponse の型の詳細を取得したい場合は以下になります。
// MicroCMSListResponse から contents の型定義を定義
// type PostsContenstReturnType = (PostType & MicroCMSContentId & MicroCMSDate)[]
type PostsContenstReturnType = Awaited<ReturnType<typeof getPosts>>['contents']
さらに contents のオブジェクトの型定義を取り出す方法です。
配列型(例えばPostType[])からその要素であるオブジェクトの型(PostType)を取り出すには、次のように infer やIndexed Access Typesを利用します。
type ArrayElementType<T> = T extends (infer U)[] ? U : T;
// infer の利用
type PostObjectType = ArrayElementType<MicroCMSListResponse<PostType>['contents']>;
// Indexed Access Types
type PostObjectTypeAlt = MicroCMSListResponse<PostType>['contents'][number];
型定義の詳細はざっくりこのブログのリポジトリから確認することができます。ぜひ参考になればと思います。