【Nuxt3】useFetchの戻り値の型を得る方法
useFetchの戻り値の型だけを得たいときってありますよね(あるはず)
TypeScript も 4.9 になりsatisfiesが使えるようになったことでtypeofを使う機会が増えました。そこで、useFetchにおける戻り値の型を取得する方法を提示します。
結論
useFetchの戻り値の型を取得する型は以下の通りです。
type ReturnFetchType<T extends string> = ReturnType<
typeof useFetch<void, unknown, T>
>["data"];
仕組み
まず、useFetchの型定義を見てみましょう
export declare function useFetch<
ResT = void,
ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest,
_ResT = ResT extends void ? FetchResult<ReqT> : ResT,
Transform extends (res: _ResT) => any = (res: _ResT) => _ResT,
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
>(
request: Ref<ReqT> | ReqT | (() => ReqT),
opts?: UseFetchOptions<_ResT, Transform, PickKeys>
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>;
わけがわかりませんね。
では、具体例でみてみましょう。
/api/profileというユーザのプロフィールを返す api があったとします。
const { data } = useFetch("/api/profile");
とした際に、dataの型は以下のようになるとします。
Ref<
| {
state: 200;
data: {
profile: {
userId: string;
displayName: string;
screenName: string;
profileImageUrl: string;
};
};
}
| {
state: 500;
data: null;
}
| {
state: 400;
data: null;
}
| null
>;
このとき、useFetch('/api/profile')にカーソルを合わせると、このように表示されます。
const useFetch: <void, FetchError<any>, "/api/profile", {
state: 200;
data: {
profile: {
userId: string;
displayName: string;
screenName: string;
profileImageUrl: string;
};
};
} | {
state: 500;
data: null;
} | {
...;
}, (res: {
state: 200;
data: {
profile: {
userId: string;
displayName: string;
screenName: string;
profileImageUrl: string;
};
};
} | ... 1 more ... | {
...;
}) => {
state: 200;
data: {
profile: {
userId: string;
displayName: string;
screenName: string;
profileImageUrl: string;
};
};
} | ... 1 more ... | {
...;
}, KeyOfRes<...>>(request: "/api/profile" | ... 1 more ... | (() => "/api/profile"), opts?:
UseFetchOptions<...> | undefined) => AsyncData<...>
型引数の 3 番目に/api/profileという文字列が現れましたね。どうやら、この第 3 引数にrequestを指定すれば戻り値が得られそうです。
では、結論の型定義をみていきましょう。
type ReturnFetchType<T extends string> = ReturnType<
typeof useFetch<void, unknown, T>
>["data"];
まず、ReturnTypeは引数に指定した関数の戻り値を返す型です。今回は、useFetchにrequestを指定した際の戻り値のAsyncDataを得ることが目的なので使用しています。
次に、typeof useFetch<void, unknown, T>についてですが、まず、typeofで型定義内でuseFetchを扱えるようにします。次に、第 3 引数にrequestを指定します。ここでいうTはrequestに該当します。第 1 引数と第 2 引数に関してはなんでもいいので適当にvoidとunknownを指定しておきます。
そして、ReturnTypeで得られたAsyncDataのdataの中に目的の型があるので、['data']とすることで最終的に目的の型を得ることができます。
実際に使用する際には以下の通りにします。
type Data = ReturnFetchType<"/api/profile">;
Dataにカーソルを合わせると、
Ref<
| {
state: 200;
data: {
profile: {
userId: string;
displayName: string;
screenName: string;
profileImageUrl: string;
};
};
}
| {
state: 500;
data: null;
}
| {
state: 400;
data: null;
}
| null
>;
と、しっかり型を得られていることがわかります。ちなみに、Refが要らない場合は
type ReturnFetchType<T extends string> = UnwrapRef<
ReturnType<typeof useFetch<void, unknown, T>>["data"]
>;
とすることでRefを外せます。
おわりに
それにしてもuseFetchの型定義はすごいですね。
Discussion