So is this the same issue, or am I just missing something?
import * as React from 'react';
interface Props {
value: string;
}
const MyComponent = (props: Props) => {
const { value, ...rest } = props;
return (
<input {...rest} type="text" value={value} />
);
}
interface ParentState {
searchText: string;
}
class ParentComponent extends React.Component<{}, ParentState> {
state: ParentState = {
searchText: ''
};
onSearchTextChanged = (e: React.FormEvent<HTMLInputElement>) => {
this.setState({
searchText: e.currentTarget.value
});
}
render() {
const { searchText } = this.state;
return (
<div>
<h2>Some Text</h2>
<MyComponent value={searchText} onChange={this.onSearchTextChanged} className="search-input" placeholder="Enter text"/>
// Errors here
</div>
)
}
}
export default ParentComponent
When I have my props for MyComponent defined in an interface, I get the following error:
error TS2339: Property 'onChange' does not exist on type 'IntrinsicAttributes & Props'.
However if I change the props type to any, it compiles just fine.
const MyComponent = (props: any) => {
Is it possible to define the props in an interface so that there are specific props that are required, but also allow additional props to be passed in so I don't have to explicitly add them into the interface?
I'm using TypeScript 2.3.4 and React 15.5.4.
You can avoid excess property/attribute checks by adding a string index signature to your interface:
interface Props {
value: string;
// This is a string index signature.
// This means that all properties in 'Props' are assignable to
// the empty object type ({})
[propName: string]: {};
}
You could also write [propName: string]: any
but that generally makes it less safe to use in MyComponent
itself.
If you want to forward all properties of the input
element inside MyComponent
to the props of MyComponent
you can lookup what props input
(in VSCode for example, use go to definition while on the input
tag).
interface IntrinsicElements {
....
input: React.DetailedHTMLProps<React.InputHTMLAttributes<>, HTMLInputElement>;
....
}
We could use React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
as the base type for our props and we will get all properties of input
. Since DetailedHTMLProps just adds ref
to React.InputHTMLAttributes<HTMLInputElement>
we can use just React.InputHTMLAttributes<HTMLInputElement>
as the base interface to get all input
properties except the ref
:
import * as React from 'react'
interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
value: string;
}
const MyComponent = (props: Props) => {
const { value, ...rest } = props;
return (
<input {...rest} type="text" value={value} />
);
}
// Usage
interface ParentState { searchText :string }
class ParentComponent extends React.Component<{}, ParentState> {
state: ParentState = {
searchText: ''
};
onSearchTextChanged = (e: React.FormEvent<HTMLInputElement>) => {
this.setState({
searchText: e.currentTarget.value
});
}
render() {
const { searchText } = this.state;
return (
<div>
<h2>Some Text</h2>
<MyComponent value={searchText} onChange={this.onSearchTextChanged} className="search-input" placeholder="Enter text"/>
</div>
)
}
}
export default ParentComponent
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