It seems this concept is so basic, there's a lack of documentation about it. I can pass objects as props, but can't seem to pass a basic string literal.
Functional Component
I have a functional ponent that takes a typed prop, like so:
const ChildComponent = (name: string) => {
return (
<div className={styles.childComponent}>
<p className={styles.styledName}>
{ name }
</p>
</div>
);
}
and call it like so:
<ChildComponent name="testName" />
Error
VSCode throws the error on ChildComponent
:
Type '{ name: string; }' is not assignable to type 'string'
I'm very new to Typescript, but from what I can tell, it's reading the string literal as an object.
Possible Solutions
Much of what I've read advises creating a custom typed prop, even for a single property, like so:
Type: NameProp {
name: string
}
and using that as the prop type, instead of string
.
Isn't this overkill? Or am I missing something very basic.
It seems this concept is so basic, there's a lack of documentation about it. I can pass objects as props, but can't seem to pass a basic string literal.
Functional Component
I have a functional ponent that takes a typed prop, like so:
const ChildComponent = (name: string) => {
return (
<div className={styles.childComponent}>
<p className={styles.styledName}>
{ name }
</p>
</div>
);
}
and call it like so:
<ChildComponent name="testName" />
Error
VSCode throws the error on ChildComponent
:
Type '{ name: string; }' is not assignable to type 'string'
I'm very new to Typescript, but from what I can tell, it's reading the string literal as an object.
Possible Solutions
Much of what I've read advises creating a custom typed prop, even for a single property, like so:
Type: NameProp {
name: string
}
and using that as the prop type, instead of string
.
Isn't this overkill? Or am I missing something very basic.
Share Improve this question asked Aug 14, 2022 at 10:15 dbcooperdbcooper 631 gold badge2 silver badges5 bronze badges 5- 1 You have to destructure it from props – DecPK Commented Aug 14, 2022 at 10:16
-
@DecPK Do you mean:
const ChildComponent = ({ name }: string) -> { ... }
If so, that just throws the errorProperty 'name' does not exist on type 'String'
– dbcooper Commented Aug 14, 2022 at 10:21 - @dbcooper I've added my answer please take a look – DecPK Commented Aug 14, 2022 at 10:22
-
@SergeySosunov declaring the type within curly braces throws the error
Binding element 'string' implicitly has an 'any' type.
– dbcooper Commented Aug 14, 2022 at 10:24 - It may look like an overkill, but props in React is always an object, it cannot be a string so you must create that type, otherwise you'll lose typing benefits (like passing a number to a string prop for example) – niceman Commented Aug 14, 2022 at 10:34
4 Answers
Reset to default 10const ChildComponent = ({ name }: { name: string }) => {
return (
<div className={styles.childComponent}>
<p className={styles.styledName}>{name}</p>
</div>
);
};
You have to destructure it from props
object.
props
is an object.
CODESADNBOX LINK
const ChildComponent = (props: ChildComponentProps) => {
const { name } = props; // CHANGE THAT YOU HAVE TO DO
return (
<div className={styles.childComponent}>
<p className={styles.styledName}>{name}</p>
</div>
);
};
or
const ChildComponent = ({ name }: ChildComponentProps) => {
return (
<div className={styles.childComponent}>
<p className={styles.styledName}>{name}</p>
</div>
);
};
where ChildComponentProps
is
interface ChildComponentProps {
name: string;
}
Define a prop interface the define the props parameter as object :
interface Props{
name:string
}
const ChildComponent: React.FC<Props> = ({name}) => {
return (
<div className={styles.childComponent}>
<p className={styles.styledName}>
{ name }
</p>
</div>
);
}
Props supposed to be an object. You are not the only one using this prop object.
Note that JSX is just a syntax extension use to make it easy to read & code ponents.
But this code will translate into the pure javascript code,
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
The above code will translate into before execute,
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
Later this createElement
will also return an object which will use to build the whole element tree of your application.
// Note: this structure is simplified
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
Notice the children
property ? Its also a prop which was not added by you but the React it self.
NOTE: Above code snippets are directly copied from React JS documentation.
So to answer your question,
You cannot change the type of the props object. It must be an object. The reason why you seen that error message is because you forcefully telling the type of props is an string but actually it is not.
The way you should do it is,
const ChildComponent: React.FC<{ name: string }> = ({ name }) => {
return (
<div className={styles.childComponent}>
<p className={styles.styledName}>
{ name }
</p>
</div>
);
}