Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Location type should have template for unknown for state #930

Open
elijahrdorman opened this issue Jan 14, 2022 · 3 comments
Open

Location type should have template for unknown for state #930

elijahrdorman opened this issue Jan 14, 2022 · 3 comments

Comments

@elijahrdorman
Copy link

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.

export interface Location<T = unknown> extends Path {
    state: T;
    key: Key;
}
@luotongzhou
Copy link

I thinks it's a good idea

@mkerkstra
Copy link

Passing a generic for location.state used to give a generic (see history/api-reference)
Screen Shot 2022-02-10 at 11 19 34 AM

The generic was removed in this commit.

location.state is like location.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 for URLSearchParams is not generic. And the built-in types for window.history.state is any without a generic. The only way to type check location.state or location.search or really any value on location.* is to do it at runtime and then get type hints from using type guards.

@XavierDefontaine
Copy link

XavierDefontaine commented Sep 21, 2022

@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:

  • Class:
interface IComponentProps extends IBlablaProps, IWithRouter<{ fooBar: string }> { }
  • Functional:
const location = useLocation() as ILocationState<{ fooBar: string }>;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants