This TypeScript error occurs when you assign an object that lacks required properties defined in its type or interface. TypeScript enforces that objects must include all non-optional properties.
This error (TS2739) occurs when TypeScript detects that an object literal or variable is missing one or more required properties that are defined in the target type, interface, or class. TypeScript performs strict type checking to ensure type safety, and when you try to assign an object to a type, all required properties must be present. The error message explicitly lists which properties are missing, helping you identify what needs to be added. This commonly happens when creating objects, passing props to components, implementing interfaces, or initializing class instances. TypeScript's excess property checking ensures that your objects conform to their declared shapes at compile time, preventing runtime errors. This is a core feature of TypeScript's structural type system - objects must have at least the properties required by their type, though they can have additional properties in most contexts.
Read the TypeScript error carefully - it explicitly tells you which properties are missing:
Type '{ x: string; }' is missing the following properties from type 'Y': name, ageIn this example, the type Y requires name and age properties, but the object only has x. Make a note of all missing properties listed.
The most straightforward fix is to provide all required properties:
interface Person {
name: string;
age: number;
email: string;
}
// ❌ Error: missing 'email'
const user: Person = {
name: 'Alice',
age: 30
};
// ✅ Fixed: all properties provided
const user: Person = {
name: 'Alice',
age: 30,
email: '[email protected]'
};Ensure every property required by the type is present in your object literal.
If certain properties should not be mandatory, mark them as optional using the ? operator:
interface Person {
name: string;
age: number;
email?: string; // Now optional
phone?: string; // Now optional
}
// ✅ Valid: optional properties can be omitted
const user: Person = {
name: 'Alice',
age: 30
};This is useful when properties are truly optional in your application logic.
When you need to work with objects that may not have all properties (like during updates or initialization), use TypeScript's Partial<T> utility type:
interface Person {
name: string;
age: number;
email: string;
}
// ✅ All properties are optional
const partialUser: Partial<Person> = {
name: 'Alice'
};
// Useful for update functions
function updatePerson(id: string, updates: Partial<Person>) {
// Only the provided fields will be updated
}
updatePerson('123', { age: 31 });Other useful utility types: Required<T>, Pick<T, Keys>, and Omit<T, Keys>.
For React components, ensure you pass all required props:
interface UserCardProps {
name: string;
age: number;
email: string;
}
function UserCard({ name, age, email }: UserCardProps) {
return <div>{name} - {age}</div>;
}
// ❌ Error: missing 'email' prop
<UserCard name="Alice" age={30} />
// ✅ Fixed: all props provided
<UserCard name="Alice" age={30} email="[email protected]" />
// Alternative: make email optional in the interface
interface UserCardProps {
name: string;
age: number;
email?: string;
}When a class implements an interface, it must include all required properties:
interface Vehicle {
make: string;
model: string;
year: number;
start(): void;
}
// ❌ Error: missing 'year' and 'start'
class Car implements Vehicle {
make: string;
model: string;
constructor(make: string, model: string) {
this.make = make;
this.model = model;
}
}
// ✅ Fixed: all interface members implemented
class Car implements Vehicle {
make: string;
model: string;
year: number;
constructor(make: string, model: string, year: number) {
this.make = make;
this.model = model;
this.year = year;
}
start(): void {
console.log('Engine started');
}
}Type Assertion as a Last Resort: You can bypass this error using type assertions (as or <Type> syntax), but this defeats TypeScript's type safety and should be avoided:
const user = {} as Person; // Compiles but unsafeThis can lead to runtime errors since the object truly doesn't have the required properties. Only use this in rare cases where you're absolutely certain the properties will be added dynamically.
Excess Property Checking: TypeScript treats object literals differently from variables. Object literals undergo "excess property checking" to catch typos and mistakes. If you assign an object to a variable first, then assign that variable to a typed variable, the excess property check is bypassed.
strictNullChecks: With strictNullChecks enabled in your tsconfig.json, properties typed as non-nullable cannot be undefined or null, which can also trigger this error if you try to initialize them incompletely.
Index Signatures: For objects with dynamic properties, consider using index signatures:
interface FlexiblePerson {
name: string;
age: number;
[key: string]: string | number; // Allows additional properties
}Branded Types: For cases where you need to ensure an object is fully formed before use, consider branded types or factory functions that guarantee complete object construction.
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript