【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