-
-
Save swyxio/37a6a3d248c2d4031801f0d568904df8 to your computer and use it in GitHub Desktop.
| // // with thanks | |
| // https://dev.to/emreloper/react-router-v6-in-two-minutes-2i96 | |
| // https://github.com/ReactTraining/react-router/blob/dev/docs/installation/getting-started.md | |
| // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/9d29adedf662de685356f711951ef8b9e8342865/types/react-router/index.d.ts#L1 | |
| // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/9d29adedf662de685356f711951ef8b9e8342865/types/react-router-dom/index.d.ts#L1 | |
| // // release notes | |
| // https://github.com/ReactTraining/react-router/releases/tag/v6.0.0-alpha.3 | |
| declare module "react-router-dom" { | |
| import * as React from 'react'; | |
| /** | |
| * react-router-dom | |
| */ | |
| // new in v6 | |
| type navigateFn<T> = (to: string | number, options?: NavigateOptions<T>) => void | |
| export function useNavigate<T = Record<string, any>> (to: string | number, options?: Omit<NavigateProps<T>, 'to'>): navigateFn<T>; | |
| type NavigateOptions<T> = Omit<NavigateProps<T>, 'to'> | |
| type NavigateProps<T> = { | |
| to: string | number, | |
| replace?: boolean, | |
| state?: T | |
| } | |
| export class Navigate<T = any> extends React.Component<NavigateProps<T>>{} | |
| // existing api's | |
| export interface BrowserRouterProps { | |
| basename?: string; | |
| getUserConfirmation?: ( | |
| message: string, | |
| callback: (ok: boolean) => void | |
| ) => void; | |
| forceRefresh?: boolean; | |
| keyLength?: number; | |
| } | |
| export class BrowserRouter extends React.Component<BrowserRouterProps, any> {} | |
| export interface StaticContext { | |
| statusCode?: number; | |
| } | |
| export interface NavLinkProps<S = H.LocationState> extends LinkProps<S> { | |
| activeClassName?: string; | |
| activeStyle?: React.CSSProperties; | |
| exact?: boolean; | |
| strict?: boolean; | |
| isActive?<Params extends { [K in keyof Params]?: string }>( | |
| match: match<Params>, | |
| location: H.Location<S> | |
| ): boolean; | |
| location?: H.Location<S>; | |
| } | |
| export class NavLink<S = H.LocationState> extends React.Component< | |
| NavLinkProps<S>, | |
| any | |
| > {} | |
| export interface LinkProps<S = H.LocationState> extends React.AnchorHTMLAttributes<HTMLAnchorElement> { | |
| component?: React.ComponentType<any>; | |
| to: H.LocationDescriptor<S> | ((location: H.Location<S>) => H.LocationDescriptor<S>); | |
| replace?: boolean; | |
| innerRef?: React.Ref<HTMLAnchorElement>; | |
| } | |
| export class Link<S = H.LocationState> extends React.Component< | |
| LinkProps<S>, | |
| any | |
| > {} | |
| // new in v6 | |
| export class Outlet extends React.Component { | |
| props: {}; // denying props or children! | |
| } | |
| /** | |
| * history | |
| */ | |
| export namespace H { | |
| export type Action = 'PUSH' | 'POP' | 'REPLACE'; | |
| export type UnregisterCallback = () => void; | |
| export interface History<HistoryLocationState = LocationState> { | |
| length: number; | |
| action: Action; | |
| location: Location<HistoryLocationState>; | |
| push(path: Path, state?: HistoryLocationState): void; | |
| push(location: LocationDescriptorObject<HistoryLocationState>): void; | |
| replace(path: Path, state?: HistoryLocationState): void; | |
| replace(location: LocationDescriptorObject<HistoryLocationState>): void; | |
| go(n: number): void; | |
| goBack(): void; | |
| goForward(): void; | |
| block( | |
| prompt?: boolean | string | TransitionPromptHook<HistoryLocationState>, | |
| ): UnregisterCallback; | |
| listen(listener: LocationListener<HistoryLocationState>): UnregisterCallback; | |
| createHref(location: LocationDescriptorObject<HistoryLocationState>): Href; | |
| } | |
| export type Location<S = LocationState> = { | |
| pathname: Pathname; | |
| search: Search; | |
| state: S; | |
| hash: Hash; | |
| key?: LocationKey; | |
| } | |
| export interface LocationDescriptorObject<S = LocationState> { | |
| pathname?: Pathname; | |
| search?: Search; | |
| state?: S; | |
| hash?: Hash; | |
| key?: LocationKey; | |
| } | |
| export namespace History { | |
| export type LocationDescriptor<S = LocationState> = Path | LocationDescriptorObject<S>; | |
| export type LocationKey = string; | |
| export type LocationListener<S = LocationState> = ( | |
| location: Location<S>, | |
| action: Action, | |
| ) => void; | |
| // The value type here is a "poor man's `unknown`". When these types support TypeScript | |
| // 3.0+, we can replace this with `unknown`. | |
| type PoorMansUnknown = {} | null | undefined; | |
| export type LocationState = PoorMansUnknown; | |
| export type Path = string; | |
| export type Pathname = string; | |
| export type Search = string; | |
| export type TransitionHook<S = LocationState> = ( | |
| location: Location<S>, | |
| callback: (result: any) => void, | |
| ) => any; | |
| export type TransitionPromptHook<S = LocationState> = ( | |
| location: Location<S>, | |
| action: Action, | |
| ) => string | false | void; | |
| export type Hash = string; | |
| export type Href = string; | |
| } | |
| export type LocationDescriptor<S = LocationState> = History.LocationDescriptor<S>; | |
| export type LocationKey = History.LocationKey; | |
| export type LocationListener<S = LocationState> = History.LocationListener<S>; | |
| export type LocationState = History.LocationState; | |
| export type Path = History.Path; | |
| export type Pathname = History.Pathname; | |
| export type Search = History.Search; | |
| export type TransitionHook<S = LocationState> = History.TransitionHook<S>; | |
| export type TransitionPromptHook< | |
| S = LocationState | |
| > = History.TransitionPromptHook<S>; | |
| export type Hash = History.Hash; | |
| export type Href = History.Href; | |
| } | |
| /** | |
| * react-router | |
| */ | |
| // new in v6 | |
| export function useRoutes(routeArray: RouteProps[]): Routes | |
| export function useSearchParams(): URLSearchParams | |
| // used to be SwitchProps | |
| export interface RoutesProps { | |
| children?: React.ReactNode; | |
| location?: H.Location; | |
| } | |
| // used to be Switch | |
| export class Routes extends React.Component<RoutesProps, any> {} | |
| export interface RouteComponentProps< | |
| Params extends { [K in keyof Params]?: string } = {}, | |
| C extends StaticContext = StaticContext, | |
| S = H.LocationState | |
| > { | |
| history: H.History<S>; | |
| location: H.Location<S>; | |
| match: match<Params>; | |
| staticContext?: C; | |
| } | |
| export interface match<Params extends { [K in keyof Params]?: string } = {}> { | |
| params: Params; | |
| isExact: boolean; | |
| path: string; | |
| url: string; | |
| } | |
| export interface RouteProps { | |
| location?: H.Location; | |
| element?: React.ReactNode; // SWYX: shortcut; have to do see if we can do better | |
| render?: (props: RouteComponentProps<any>) => React.ReactNode; | |
| children?: | |
| // | ((props: RouteChildrenProps<any>) => React.ReactNode) // SWYX: i think this is not needed anymore? | |
| | RouteProps[] // new in v6 | |
| | React.ReactNode; | |
| path?: string | string[]; | |
| sensitive?: boolean; | |
| // // no more in v6 | |
| // component?: | |
| // | React.ComponentType<RouteComponentProps<any>> | |
| // | React.ComponentType<any>; | |
| // exact?: boolean; | |
| // strict?: boolean; | |
| } | |
| export class Route<T extends RouteProps = RouteProps> extends React.Component< | |
| T, | |
| any | |
| > {} | |
| } |
thanks @cdaz5 i removed it (i backed up v6.0.0-alpha2 typings here) and also added export function useSearchParams(): URLSearchParams
thanks! think also need to include
string | numberin the following places:export function useNavigate(): (to: string | number, options?: Omit<NavigateProps<T>, 'to'>) => navigateFn; type NavigateProps<T> = { to: string | number, replace?: boolean, state?: T }
right in order to support navigate(-1) instead of goBack()
remix-run/react-router#7159 (comment)
ah thanks @gitpash
export function useNavigate(T = object): (to: string | number, options?: Omit<NavigateProps<T>, 'to'>) => navigateFn; do you mean T = Object?
tbh i havent really tested that code (since my project doesnt need it) - can we do better than Object? what should we really be putting there?
tbh i havent really tested that code (since my project doesnt need it) - can we do better than
Object? what should we really be putting there?
Was looking at it more closely
export function useNavigate(T = object): (to: string | number, options?: Omit<NavigateProps<T>, 'to'>) => navigateFn;
type NavigateOptions<T> = Omit<NavigateProps<T>, 'to'>
type NavigateProps<T> = {
to: string | number,
replace?: boolean,
state?: T
}
not sure why passing T = Object as a prop to useNavigate (I'm not familiar with such pattern)
in my perspective main reason is to explicitly describe the shape of state prop in NavigateProps, if so
export function useNavigate<T>(): (to: string | number, options?: Omit<NavigateProps<T>, 'to'>) => navigateFn; - should be enough
but for more accuracy in order to define object like shape (to prevent smth like useNavigate<string>) we can use Metaobject
interface MetadataObj {
[key: string]: any;
}
export function useNavigate<T extends MetadataObj>(): (
to: string | number,
options?: Omit<NavigateProps<T>, 'to'>
) => navigateFn;
this seems to be ok in my project
not sure why passing T = Object as a prop to useNavigate (I'm not familiar with such pattern)
that was a typo. I meant to write useNavigate<T = Object> instead - basically saying i declare a generic type T, and if the user doesnt give me anything, i'll just give it a default of Object.
ok i hear you - thats good enough for me to work with. i'll fix it up, cheers
thank you! really appreciate your work here and in other projects 👍 I'm happy if I can help in any way
there is finally an attempt to update types on definitelytyped - see @murbanowicz's work here DefinitelyTyped/DefinitelyTyped#44015
i dont intend to maintain typings here much longer as i dont currently actively use RR
I will appreciate any help with moving it forward! @gitpash
according to the new major changes here https://github.com/ReactTraining/react-router/releases/tag/v6.0.0-alpha.3 .. redirect was removed FYI