Nuxt3의useFetch의 장르 정의를 탐색해보면 재밌을 것 같아요.
30702 단어 nuxtTypeScriptNuxt 3tech
며칠 전 10월 12일 Nuxt3가 Public beta가 되었습니다!🎉
Nuxt2에서 철저히 변경된 Nuxt3는 흥미로운 변경점이 많은데, 이번에는 useFetch의 행동에 대한 탐색을 진행한다.
이른바 useFetch?
Data Fetching에 설명된 비동기식 데이터 획득 API 중 하나입니다.
useFetch(url: string, options?)
과 같은 형식으로 호출된 매우 간단한 API이지만 useAsyncData
와$fetch
의 잠금 메모리를 제공하고 자동으로 생성된 로컬 API의 응답 유형을 제공하기 때문에 유형 정의가 상당히 복잡해졌다.먼저 유형 정의부터 시작합니다.
useFetch의 유형 정의는 다음과 같습니다.
export declare function useFetch<ReqT extends string = string, ResT = FetchResult<ReqT>, Transform extends (res: ResT) => any = (res: ResT) => ResT, PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>>(url: ReqT, opts?: UseFetchOptions<ResT, Transform, PickKeys>): import("./asyncData").AsyncData<import("./asyncData").PickFrom<ReturnType<Transform>, PickKeys>>;
퍼즐감이 대단한데...여기서부터 하나씩 풀어볼게요.
Transform 벗기기
Transform
useAsyncData의 옵션 중 하나입니다. 반환값의 변환기이기 때문에 먼저 깎아서 간단하게 하겠습니다.export declare function _useFetch<ReqT extends string = string, ResT = FetchResult<ReqT>, PickKeys = KeysOf<ResT>>(url: ReqT, opts?: UseFetchOptions<ResT, (input: ResT)=> ResT, PickKeys>): import("./asyncData").AsyncData<import("./asyncData").PickFrom<ResT, PickKeys>>;
※ 이 경우 UseFetchOptions의 제3형 매개 변수는 오류가 발생하지만, 의도적으로 유형의 추상도를 바꾸었기 때문에 잠시 무시반환 값 주의
이곳에서 귀환치를 주목해 보자.
asyncData.d.ts
에서 다음과 같이 정의한다.// Tのうち、Kの配列の要素に指定されたkeyの要素だけを抽出して取り出す
export declare type PickFrom<T, K extends Array<string>> = T extends Record<string, any> ? Pick<T, K[number]> : T;
...
// Dataの型を、asyncDataが返してくれる型に変換する
export interface _AsyncData<DataT> {
data: Ref<DataT>;
pending: Ref<boolean>;
refresh: (force?: boolean) => Promise<void>;
error?: any;
}
export declare type AsyncData<Data> = _AsyncData<Data> & Promise<_AsyncData<Data>>;
반환값은'ResT
에서 PickKeys
로 지정된 요소만 가져와 asyncData 반환 형식으로 전환하는 유형'이다.Rest 검색
그럼
ResT
도 탐색해 보세요.ResT = FetchResult<ReqT>;
export declare type Awaited<T> = T extends Promise<infer U> ? U : T;
export declare type FetchResult<ReqT extends string> = Awaited<ReturnType<$Fetch<unknown, ReqT>>>;
이기 때문에 "ResT
는 $Fetch<unknown, ReqT>
의 반환치를 벗긴 프로미스 또는 자신이다."$Fetch의 탐색
$Fetch
는 다음과 같다.export declare interface $Fetch<T = unknown, R extends FetchRequest = FetchRequest> {
(request: R, opts?: FetchOptions): Promise<TypedInternalResponse<R, T>>
raw (request: R, opts?: FetchOptions): Promise<FetchResponse<TypedInternalResponse<R, T>>>
}
ResT
컴퓨팅 의합ResT
에 필요한 정보만 남는 경우export declare interface $Fetch<unknown, ReqT> {
(request: R, opts?: FetchOptions): Promise<TypedInternalResponse<ReqT, unknown>>
}
.TypedInternalResponse
는 다음과 같다.export declare type TypedInternalResponse<Route, Default> =
Default extends string | boolean | number | null | void | object
// Allow user overrides
? Default
: Route extends string
? MiddlewareOf<Route> extends never
// Bail if only types are Error or void (for example, from middleware)
? Default
: MiddlewareOf<Route>
: Default
이번 모델로 바꾸면export declare type TypedInternalResponse<ReqT, unknown> =
ReqT extends string
? MiddlewareOf<ReqT> extends never
// Bail if only types are Error or void (for example, from middleware)
? unknown
: MiddlewareOf<ReqT>
: unknown
.네버MiddlewareOf<ReqT>
를 무시하면 답장이 온다고 한다.나머지 유형 정의는 다음과 같다.
적용
export declare interface InternalApi { }
export declare type ValueOf<C> = C extends Record<any, any> ? C[keyof C] : never
export declare type MatchedRoutes<Route extends string> = ValueOf<{
// exact match, prefix match or root middleware
[key in keyof InternalApi]: Route extends key | `${key}/${string}` | '/' ? key : never
}>
export declare type MiddlewareOf<Route extends string> = Exclude<InternalApi[MatchedRoutes<Route>], Error | void>
MiddlewareOf<ReqT>
해보면export declare interface InternalApi { }
export declare type ValueOf<C> = C extends Record<any, any> ? C[keyof C] : never
export declare type MatchedRoutes = ValueOf<{
// exact match, prefix match or root middleware
[key in keyof InternalApi]: ReqT extends key | `${key}/${string}` | '/' ? key : never
}>
export declare type MiddlewareOf = Exclude<InternalApi[MatchedRoutes<ReqT>], Error | void>
.대략적으로'InternalApi
중 ReqT
가 관건이 되는 것이 있다면 그 밸류(Value)를 반납하라'는 의미로 해석된다.즉'
ResT
는 InternalApi
의 키가 ReqT
의 밸류에 해당하는 유형'이라고 추정할 수 있다.인터넷 Api 자동 생성
상기 유형 정의
InternalApi
는 기본값{}
이다.이대로 가면 아무런 의미가 없다는 얘기다.이 유형의 정의를 완성할 수 있는 것은 Nuxt3의 서버 엔진
nitro
이다.nitro
에는 다양한 기능이 있는데 그 중 하나/server/
디렉터리에 설정된 함수의 반환값을 설명하고 형식 정의를 생성한다.예를 들어, 다음 TS 파일
/server/api/count.ts
을 설정합니다.let counter = 0;
export default (): { counter: number } => {
counter++;
return { counter };
};
다음 내용의 파일을 생성.nuxt/nitro.d.ts
.declare module '@nuxt/nitro' {
interface InternalApi {
'/api/count': ReturnType<typeof import('../server/api/count').default>
}
}
export {}
InternalApi
가 확장된 후 /api/count
에 대한 유형 정의가 나타났다.따라서 "Value의 유형
ResT
이 InternalApi
에 대응하는ReqT
"은"
ResT
는 ReqT
가 /api/count
일 때/server/api/count
의 반환값이다."useFetch의 반환값
이 효과를 탐색하기 위해useFetch를 실제로 사용합니다.
const {data} = await useFetch('/api/count')
시 data
의 유형은 간단해야 한다Ref<Pick<{
counter: number;
}, "counter">>
.useFetch에서 단점을 지정한 것에 불과하지만 그 반환값은 Vue3에서 쉽게 사용할 수 있는 유형으로 추출된 것으로 보인다.
InternalApi
의 디자인은 유형 정의가 없어도 사용할 수 있는 것으로 useFetch
의 매개 변수의 보완이 작용하지 않는 것이 어려운 점이지만 Nuxt의 디렉터리 구조를 검색하면 파일 이름만 어느 정도 예측할 수 있어 편리하게 사용할 수 있다.아무튼 일단 정리를 해볼게요.
다만 useFetch를 검색하면 되돌아오는 값이 상당히 길어서 잠시 여기서 끝냅니다.
이 외에도
useAsyncData
와 $fetch
옵션이 지원됩니다. 가능하면 검색해 보세요.옵션의 지원은 위의 것과 비교하면 그리 대단한 일이 아니기 때문에 걱정하지 않아도 된다
Reference
이 문제에 관하여(Nuxt3의useFetch의 장르 정의를 탐색해보면 재밌을 것 같아요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/kotamat/articles/ec36414b696c12텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)