https://www.typescriptlang.org/docs/handbook/declaration-merging.html
The above link provides information on declaration merging with interfaces. I'd like to be able to do that with an interface that's got a generic component. I'm currently using Typescript 3.0.3.
This does what I want, but I don't understand why I can't do the same thing with declaration merging.
interface MyRouteComponentProps<P, C extends StaticContext = StaticContext> extends RouteComponentProps<P, C> {
loadCandidateFromQueryParam: (candidateId: number) => void
}
class CandidateDetailContainer extends React.Component<MyRouteComponentProps<RouteMatchProps>, {}> {
public componentWillMount() {
this.props.loadCandidateFromQueryParam(Number(this.props.match.params.candidateId));
}
Why doesn't this work?
interface RouteComponentProps<P, C extends StaticContext = StaticContext> {
loadCandidateFromQueryParam: (candidateId: number) => void
}
class CandidateDetailContainer extends React.Component<RouteComponentProps<RouteMatchProps>, {}> {
It seems to completely override the entire definition for RouteComponentProps instead of merging them. I get errors related to P and C never being used (if the definitions were merged then I would expect those errors to go away because they're used in the primary definition). And then I get an error about "match" field not being there. Again, another field that was present in the original definition.
For reference here's the original definition that I'm trying to merge with.
export interface RouteComponentProps<P, C extends StaticContext = StaticContext> {
history: H.History;
location: H.Location;
match: match<P>;
staticContext: C | undefined;
}
In fact, in your second example, when I add the imports that I assume you must have:
import * as React from "react";
import { RouteComponentProps, StaticContext } from "react-router";
I get an error on the import of RouteComponentProps
.
You can't merge content into an imported symbol (interface, namespace, etc.) by declaring a local symbol of the same name; either this will be an error or it will shadow the imported symbol. To merge definitions, they must be in the same scope. In the case of merging content into a symbol from a module, you can use a module augmentation to put your definition in the scope of the original module:
declare module "react-router" {
interface RouteComponentProps<Params, C extends StaticContext = StaticContext> {
loadCandidateFromQueryParam: (candidateId: number) => void
}
}
(What makes this a module augmentation rather than a module declaration is that it is nested inside another module. Obscure, I know.) Note that the names of the type parameters have to be the same as in the original interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With