I saw the following viewpoint on the React TypeScript Cheatsheet website: "An empty interface, {} and Object all represent "any non-nullish value"—not "an empty object" as you might think."
For example:
let value: {};
value = 1;
value = "foo";
value = () => alert("foo");
value = {};
value = { foo: "bar" };
value = undefined; // Error Type
value = null; // Error Type
But it doesn’t seem to work that way in React.
As shown in the code below, if {} means non-empty values, it would imply that the Child component’s props could accept any non-empty parameters. However, when I tried to pass an id to the Child component, it resulted in an error.
const Child:FC<{}> = (props) => {
return (
<div>
Child
</div>
)
}
const App = () => {
return (
{/**Error: Type '{ id: string; }' is not assignable to type 'IntrinsicAttributes'.**/}
<Child id={'111'}/>
);
}
I would like to receive a fundamental explanation.
2
Answers
It does not represent an empty object or a type that expects an empty object.
Instead, it represents a type that can accept any value that is not null or undefined.
When you define a React component with
FC<{}>
, you’re saying that this component accepts NO props at all. This is because{}
is interpreted as the props object cannot contain any keys. So{}
means no keys.The type
{}
means that the props object is an empty object. When you try to pass{ id: '111' }
, TypeScript raises an error becauseid
is not a key that{}
allows—since{}
is supposed to have no keys at all!If you want a
Child
component to accept any props, here is how you can do it:Record<string, unknown>
is a TypeScript utility type that represents an object with string keys and values of any type. It is equivalent to{ [key: string]: unknown }
.unknown
specifies that the values can be of any type, but their exact type is not known at compile time.or if you want the Child to accept
id
as a prop: