[英]extending nextJS default types with typescript
目前我正在這樣做
路由器.d.ts
import { useRouter } from 'next/router'
declare global {
type TRouter = ReturnType<typeof useRouter> & {
query: {
ticketNumber: string
}
}
}
並像這樣使用它:
const { query } = useRouter() as TRouter
我嘗試避免as
並使用我的自定義類型擴展 nextJS 類型是
下一個環境.d.ts
/// <reference types="next" />
/// <reference types="next/types/global" />
import * as router from 'next/router'
declare module 'next/router' {
function useRouter(): ReturnType<typeof router.useRouter> & {
query: {
ticketNumber: string
}
}
export { useRouter }
}
但這似乎完全破壞了模塊next/router
的類型..
對於模塊擴充,您需要擴展默認類型的useRouter()
並吸收您的自定義集成。
用戶路由器的定義
/// <reference types="node" />
import React from 'react';
import Router, { NextRouter } from '../next-server/lib/router/router';
declare type SingletonRouterBase = {
router: Router | null;
readyCallbacks: Array<() => any>;
ready(cb: () => any): void;
};
export { Router, NextRouter };
export declare type SingletonRouter = SingletonRouterBase & NextRouter;
declare const _default: SingletonRouter;
export default _default;
export { default as withRouter } from './with-router';
export declare function useRouter(): NextRouter;
export declare const createRouter: (pathname: string, query: import("querystring").ParsedUrlQuery, as: string, __3: {
subscription: (data: import("../next-server/lib/router/router").PrivateRouteInfo, App: React.ComponentType<import("../next-server/lib/router/router").AppProps>, resetScroll: {
x: number;
y: number;
} | null) => Promise<void>;
initialProps: any;
pageLoader: any;
Component: React.ComponentType<{}>;
App: React.ComponentType<import("../next-server/lib/router/router").AppProps>;
wrapApp: (WrapAppComponent: React.ComponentType<import("../next-server/lib/router/router").AppProps>) => any;
err?: Error | undefined;
isFallback: boolean;
locale?: string | undefined;
locales?: string[] | undefined;
defaultLocale?: string | undefined;
domainLocales?: import("../next-server/server/config-shared").DomainLocales | undefined;
isPreview?: boolean | undefined;
}) => Router;
export declare function makePublicRouterInstance(router: Router): NextRouter;
useRouter 的類型為function useRouter(): NextRouter
NextRouter 定義為
type NextRouter = BaseRouter & Pick<Router, "push" | "replace" | "reload" | "back" | "prefetch" | "beforePopState" | "events" | "isFallback" | "isReady" | "isPreview">
因此,您可以擴展BaseRouter
type BaseRouter = {
route: string;
pathname: string;
query: ParsedUrlQuery;
asPath: string;
basePath: string;
locale?: string;
locales?: string[];
defaultLocale?: string;
domainLocales?: DomainLocales;
isLocaleDomain: boolean;
}
在您調用 useRouter() 時定義
或者
您可以擴展 class Router
,實現 BaseRouter,這將允許您有條件地選擇您正在合並的類型,同時不損害默認路由器的完整性
export default class Router implements BaseRouter {
route: string;
pathname: string;
query: ParsedUrlQuery;
asPath: string;
basePath: string;
/**
* Map of all components loaded in `Router`
*/
components: {
[pathname: string]: PrivateRouteInfo;
};
sdc: {
[asPath: string]: object;
};
sdr: {
[asPath: string]: Promise<object>;
};
sub: Subscription;
clc: ComponentLoadCancel;
pageLoader: any;
_bps: BeforePopStateCallback | undefined;
events: MittEmitter;
_wrapApp: (App: AppComponent) => any;
isSsr: boolean;
isFallback: boolean;
_inFlightRoute?: string;
_shallow?: boolean;
locale?: string;
locales?: string[];
defaultLocale?: string;
domainLocales?: DomainLocales;
isReady: boolean;
isPreview: boolean;
isLocaleDomain: boolean;
private _idx;
static events: MittEmitter;
constructor(pathname: string, query: ParsedUrlQuery, as: string, { initialProps, pageLoader, App, wrapApp, Component, err, subscription, isFallback, locale, locales, defaultLocale, domainLocales, isPreview, }: {
subscription: Subscription;
initialProps: any;
pageLoader: any;
Component: ComponentType;
App: AppComponent;
wrapApp: (WrapAppComponent: AppComponent) => any;
err?: Error;
isFallback: boolean;
locale?: string;
locales?: string[];
defaultLocale?: string;
domainLocales?: DomainLocales;
isPreview?: boolean;
});
onPopState: (e: PopStateEvent) => void;
reload(): void;
/**
* Go back in history
*/
back(): void;
/**
* Performs a `pushState` with arguments
* @param url of the route
* @param as masks `url` for the browser
* @param options object you can define `shallow` and other options
*/
push(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
/**
* Performs a `replaceState` with arguments
* @param url of the route
* @param as masks `url` for the browser
* @param options object you can define `shallow` and other options
*/
replace(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
private change;
changeState(method: HistoryMethod, url: string, as: string, options?: TransitionOptions): void;
handleRouteInfoError(err: Error & {
code: any;
cancelled: boolean;
}, pathname: string, query: ParsedUrlQuery, as: string, routeProps: RouteProperties, loadErrorFail?: boolean): Promise<CompletePrivateRouteInfo>;
getRouteInfo(route: string, pathname: string, query: any, as: string, resolvedAs: string, routeProps: RouteProperties): Promise<PrivateRouteInfo>;
set(route: string, pathname: string, query: ParsedUrlQuery, as: string, data: PrivateRouteInfo, resetScroll: {
x: number;
y: number;
} | null): Promise<void>;
/**
* Callback to execute before replacing router state
* @param cb callback to be executed
*/
beforePopState(cb: BeforePopStateCallback): void;
onlyAHashChange(as: string): boolean;
scrollToHash(as: string): void;
urlIsNew(asPath: string): boolean;
/**
* Prefetch page code, you may wait for the data during page rendering.
* This feature only works in production!
* @param url the href of prefetched page
* @param asPath the as path of the prefetched page
*/
prefetch(url: string, asPath?: string, options?: PrefetchOptions): Promise<void>;
fetchComponent(route: string): Promise<GoodPageCache>;
_getData<T>(fn: () => Promise<T>): Promise<T>;
_getStaticData(dataHref: string): Promise<object>;
_getServerData(dataHref: string): Promise<object>;
getInitialProps(Component: ComponentType, ctx: NextPageContext): Promise<any>;
abortComponentLoad(as: string, routeProps: RouteProperties): void;
notify(data: PrivateRouteInfo, resetScroll: {
x: number;
y: number;
} | null): Promise<void>;
}
For example, I extended AppProps here to incorporate a Session
object so that I can call pageProps.session
to inject NextAuth
with a users session object
next.d.ts
import type { NextComponentType, NextPageContext } from 'next';
import type { Session } from 'next-auth';
import type { Router } from 'next/router';
declare module 'next/app' {
type AppProps<P = Record<string, unknown>> = {
Component: NextComponentType<NextPageContext, any, P>;
router: Router;
__N_SSG?: boolean;
__N_SSP?: boolean;
pageProps: P & {
/** Initial session passed in from `getServerSideProps` or `getInitialProps` */
session?: Session;
};
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.