Open elijahrdorman opened 2 years ago
I thinks it's a good idea
Passing a generic for location.state used to give a generic (see history/api-reference)
The generic was removed in this commit.
location.state
is likelocation.search
, there's no way for a type system to do its job with a value that isn't controlled by the code. Similarly, the DOM type forURLSearchParams
is not generic. And the built-in types forwindow.history.state
isany
without a generic. The only way to type checklocation.state
orlocation.search
or really any value onlocation.*
is to do it at runtime and then get type hints from using type guards.
@elijahrdorman Seconded. This temporarily fixed the problem for me with the Class hoc:
export interface ILocationState<Type> extends Omit<Location, 'state'> { state: any | Type };
export interface IWithRouter<Type = any> { //TODO: make this a mandatory Type so it's easier to keep track of State between components.
router: {
location: ILocationState<Type>;
navigate: NavigateFunction;
params: Readonly<Params<string>>;
}
}
};
Usage:
interface IComponentProps extends IBlablaProps, IWithRouter<{ fooBar: string }> { }
const location = useLocation() as ILocationState<{ fooBar: string }>;
Any typesafe use of Location requires casting the unknown type into something else (casting is usually a code smell). My primary use for this is in React Router with the
useLocation
hook when accessing the state property.It seems like a template variable would fix this up. Perhaps something like this would work.