Understanding the "Object Literal May Only Specify Known Properties" Error in React + TypeScript
When working with useState
and TypeScript in a React project, you might encounter this confusing TypeScript error:
Object literal may only specify known properties, and 'uid' does not exist in type '(prevState: undefined) => undefined'.ts(2353)
Let’s unpack this error, why it happens, and how to properly fix it while demonstrating best practices in state typing using a real-world example.
Problem Overview
Consider the following component:
import { useState } from "react";
export const User = () => {
const [user, setUser] = useState();
const login = () => {
setUser({
uid: 'ABC123',
name: 'Fernando'
});
}
return (
<div className="mt-5">
<h3>User: useState</h3>
<button className="btn btn-outline-primary">Login</button>
</div>
)
}
When you run this, you might get an error like:
Object literal may only specify known properties, and 'uid' does not exist in type '(prevState: undefined) => undefined'.
Why?
Root Cause
The issue is simple: you did not define a type for the user
state. TypeScript assumes useState()
holds undefined
, so when you try to set it with an object, it complains:
“I don’t know what
uid
orname
is supposed to be.”
Solution: Define a Type or Interface
interface User {
uid: string;
name: string;
}
export const UserComponent = () => {
const [user, setUser] = useState<User | null>(null);
const login = () => {
setUser({
uid: 'ABC123',
name: 'Fernando'
});
}
return (
<div className="mt-5">
<h3>User: useState</h3>
<button className="btn btn-outline-primary" onClick={login}>Login</button>
{user && (
<pre>{JSON.stringify(user, null, 2)}</pre>
)}
</div>
)
}
What’s Happening Behind the Scenes?
When you write useState()
, TypeScript infers the type from the initial value. If no value is passed, the type is undefined
.
But when you provide a generic, like useState<User | null>(null)
, TypeScript now expects an object with uid
and name
fields, or null
.
This enables:
- Autocompletion
- Type safety
- Better debugging
Why It Matters
React + TypeScript is powerful, but only when used correctly:
Without Typing | With Typing (User - null ) |
---|---|
Error-prone | Type-safe and predictable |
No autocompletion | Full IntelliSense for user.uid
|
Can pass anything to setUser
|
Only valid User objects or null |
Best Practices for useState
with Objects
Tip | Description |
---|---|
Always type your state | Especially when managing complex structures |
Use - null for optional states |
Makes checks like if (user) safe |
Prefer interfaces for clarity | Define interface User to keep types reusable |
Validate before rendering | Use conditional rendering with optional values |
Conclusion
This TypeScript error isn’t just noise—it’s a clue to improve your code's safety and structure. By defining a proper type for your state, you unlock the full power of React + TypeScript.
Don’t let the compiler scare you—embrace types, and make your components clean, robust, and production-ready.
Tags: react
typescript
useState
frontend
state-management
errors
Top comments (1)
you just can use useState< User >() because User accept undefined value