-
-
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! think also need to include
string | number
in 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
thanks @cdaz5 i removed it (i backed up v6.0.0-alpha2 typings here) and also added
export function useSearchParams(): URLSearchParams