There's not a way to do this just by passing types to useLocation
. The generic on useLocation
, which you are setting to LocationTypes
, actually refers to the property location.state
. location.pathname
is always just a string
.
You would have to either extends the typings of these packages or assert correctness via as
.
I don't have a ton of experience extending packages, so I don't know how to make this work correctly. I think you can only extend an interface and not a type? Maybe someone else knows.
declare module 'history' {
export type Pathname = keyof typeof routes;
}
The assertion approach is basically wrapping the built-in function with your own.
import {useLocation as useLocationImported} from "react-router-dom";
import {State, Location} from "history";
export const useLocation = <S extends State = State>() =>
useLocationImported<S>() as Location<S> & {pathname: routesKeys}
const location = useLocation();
const path = location.pathname; // type is "ROUTE_MAIN" | "ROUTE_DASHBOARD" | "ROUTE_DOCUMENTS" | "ROUTE_SETTINGS"
Edit: on further thought, I don't think you want to do this. These sort of typings make it so that the path is always an exact match to one of your routes, but in reality that's not the case 100% of the time. You will create problems if you assume that it is.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…