javascript - Hur man utökar en React-klass i TypeScript
Här är ett enkelt exempel:
interface BaseProps {
name: string;
}
class BaseClass<P extends BaseProps> extends React.Component<P, void> {
}
interface SuperProps {
}
class SuperClass extends BaseClass<SuperProps> {
}
Jag förväntar mig att SuperClass som standard skulle ha this.props.name. Men just nu får jag ett kompileringsfel som säger Typen 'SuperProps' uppfyller inte begränsningen 'BaseProps'. Egenskapen 'name' saknas i typen 'SuperProps'.
Vad gör jag fel? Jag inser att jag kan göra SuperProps extends BaseProps men det verkar överflödigt här.
Svar #1
class BaseClass<P extends BaseProps> extends React.Component<P, void>
där <P extends BaseProps> betyder vilken giltig typ som helst som utökar BaseProps kan tilldelas till BaseClass. Så fungerar generics.
Nu, när du gör
interface SuperProps {
}
class SuperClass extends BaseClass<SuperProps> {
}
Du tilldelar typen SuperProps som inte utökar BaseProps. Det är anledningen till att du får felet.
För att övervinna felet, som du sa, behöver du antingen utöka BaseProps-gränssnittet eller använda snitt-typer. Om du använder snitt-typer kommer hela exemplet att se ut så här:
export interface BaseProps {
name: string;
}
class BaseClass<P> extends React.Component<P & BaseProps, void> {
}
interface SuperProps {
}
class SuperClass extends BaseClass<SuperProps> {
render(): JSX.Element {
return (
<div>
{this.props.name} {/* Won't throw an error*/}
</div>
);
}
}
Du kan läsa mer om avancerade typer här.
Svar #2
Säg nu att du inte kunde modifiera BaseClass (tredjepartskod) så att det tar en generisk typ, dvs.
class BaseClass extends React.Component<BaseProps, void> {
}
Du bör fortfarande kunna omdefiniera BaseClass med utökade proptyper på följande sätt:
const SuperClass = BaseClass as React.ComponentClass<
BaseProps & {
somethingElse: string;
}
>;
Fullt exempel där SomeInput faktiskt stöder autoFocus-egenskapen men dess exporterade egenskapstypsdefinitioner gör det inte:
import { Input as SomeInput, InputPropsType as SomeInputPropsType } from 'somewhere';
const Input = SomeInput as React.ComponentClass<
SomeInputPropsType & {
autoFocus?: boolean;
}
>;
// Now passing `autoFocus` prop to `Input` should be fine
