How to fix Object literal may only specify known properties, and 'name' does not exist in type 'T'. ts(2353) in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated May 28, 2026· 240 views

TS2353 fires when an object literal has a property not in the target type. Fix the typo, widen the type, or assert with 'as'.

Quick fix

Fixes Object literal may only specify known properties, and 'name' does not exist in type 'T'. ts(2353)

interface User {
  name: string;
  age: number;
}

// ERROR: 'email' doesn't exist in User
function saveUser(user: User) {}

saveUser({ name: 'John', age: 30, email: 'john@example.com' });
// Object literal may only specify known properties...

// FIX: Remove the extra property
saveUser({ name: 'John', age: 30 });

// OR if 'email' should be included, update the interface:
interface User {
  name: string;
  age: number;
  email?: string;  // Make it optional
}
  1. Remove or rename the extra properties
  2. Use a type assertion to bypass excess property checking
  3. Assign to a variable first (structural typing)
  4. Use index signatures or Record types
typescript — error
interface User {
name: string;
age: number;
}
// ERROR: 'email' doesn't exist in User
function saveUser(user: User) {}
saveUser({ name: 'John', age: 30, email: 'john@example.com' });
// Object literal may only specify known properties...
// FIX: Remove the extra property
saveUser({ name: 'John', age: 30 });
// OR if 'email' should be included, update the interface:
interface User {
name: string;
age: number;
email?: string; // Make it optional
}
Object literal may only specify known properties, and 'name' does not exist in type 'T'. ts(2353)

What this error means

The "Object literal may only specify known properties" error is TypeScript's way of enforcing strict type checking when you create object literals. This is part of TypeScript's excess property checking feature, which helps catch common bugs like typos in property names or accidentally passing extra data. When you pass an object literal directly to a function or assign it to a variable with a specific type, TypeScript performs extra validation beyond normal type compatibility. It checks that every property in the object literal exists in the target type. This prevents subtle bugs where you might think you're passing certain data but actually have a typo in a property name. For example, if you have an interface `User` with properties `name` and `age`, and you try to create `{name: 'John', age: 30, email: 'john@example.com'}` where `User` doesn't have an `email` property, TypeScript will flag this as an error. This is different from assigning an existing object variable, which would be allowed due to structural typing.

Typical symptoms

  • Compilation fails with 'Object literal may only specify known properties' error
  • IDE shows red underlines on object literals passed to typed functions
  • Error occurs when creating inline objects but not when using variables
  • Code works if you assign the object to a variable first, then pass the variable
  • Error highlights specific extra properties that don't exist in the target type
  • Common when passing configuration objects or React props

Common causes

  1. Passing an object literal with extra properties to a typed parameter
  2. Typo in property name (e.g., 'colour' instead of 'color')
  3. Using deprecated property names that were removed from the type
  4. Passing configuration objects with optional properties not declared in the type
  5. Mismatch between library versions and type definitions
  6. Incorrect type inference where TypeScript thinks you're passing to a stricter type
  7. Using object spread with extra properties in a typed context

How to fix "Object literal may only specify known properties, and 'name' does not exist in type 'T'. ts(2353)"

1Remove or rename the extra properties

The simplest fix is to remove properties that don't exist in the target type:

typescript
interface User {
  name: string;
  age: number;
}

// ERROR: 'email' doesn't exist in User
function saveUser(user: User) {}

saveUser({ name: 'John', age: 30, email: 'john@example.com' });
// Object literal may only specify known properties...

// FIX: Remove the extra property
saveUser({ name: 'John', age: 30 });

// OR if 'email' should be included, update the interface:
interface User {
  name: string;
  age: number;
  email?: string;  // Make it optional
}

Check for typos in property names:

typescript
// ERROR: Typo in 'colour' (should be 'color')
interface Config {
  color: string;
  size: number;
}

const config: Config = { colour: 'red', size: 10 };
// Object literal may only specify known properties...

// FIX: Correct the typo
const config: Config = { color: 'red', size: 10 };
2Use a type assertion to bypass excess property checking

If you're sure the extra properties are safe, use a type assertion:

typescript
interface User {
  name: string;
  age: number;
}

// ERROR: Extra 'metadata' property
saveUser({ name: 'John', age: 30, metadata: { id: 1 } });

// FIX: Use type assertion
saveUser({ name: 'John', age: 30, metadata: { id: 1 } } as User);

// OR use the newer 'as' syntax
saveUser({ name: 'John', age: 30, metadata: { id: 1 } } as User);

// WARNING: This suppresses the error but the extra property
// will be lost at runtime since TypeScript only affects type checking

For React props with spread operators:

typescript
interface ButtonProps {
  label: string;
  onClick: () => void;
}

// ERROR: Extra 'className' property
const Button = ({ label, onClick, className }: ButtonProps & { className?: string }) => {
  return <button className={className} onClick={onClick}>{label}</button>;
};

// FIX: Update the interface to include className
interface ButtonProps {
  label: string;
  onClick: () => void;
  className?: string;
}
3Assign to a variable first (structural typing)

TypeScript's structural typing allows extra properties if you assign to a variable first:

typescript
interface User {
  name: string;
  age: number;
}

// ERROR: Direct object literal
saveUser({ name: 'John', age: 30, email: 'john@example.com' });

// FIX: Assign to variable first
const userData = { name: 'John', age: 30, email: 'john@example.com' };
saveUser(userData); // This works!

// Why this works: TypeScript uses structural typing
// The variable 'userData' has at least the properties of User
// Extra properties don't break the contract

// Common pattern for configuration objects:
interface Config {
  apiUrl: string;
  timeout: number;
}

function initialize(config: Config) {}

// ERROR: Direct literal with extra debug property
initialize({ apiUrl: '/api', timeout: 5000, debug: true });

// FIX: Use variable
const appConfig = { apiUrl: '/api', timeout: 5000, debug: true };
initialize(appConfig); // Works

This approach is useful when you need to pass extra data for internal use but the function only requires a subset.

4Use index signatures or Record types

If your type should accept any additional properties, use an index signature:

typescript
// BEFORE: Strict interface
interface Config {
  apiUrl: string;
  timeout: number;
}
// ERROR: Can't pass extra properties
const config: Config = { apiUrl: '/api', timeout: 5000, retries: 3 };

// AFTER: Add index signature for extra properties
interface Config {
  apiUrl: string;
  timeout: number;
  [key: string]: any; // Allows any extra string properties
}

// Now this works:
const config: Config = { apiUrl: '/api', timeout: 5000, retries: 3 };

// More type-safe: Use Record for specific value types
interface Config {
  apiUrl: string;
  timeout: number;
  options: Record<string, string | number | boolean>;
}

const config: Config = {
  apiUrl: '/api',
  timeout: 5000,
  options: { retries: 3, debug: true, mode: 'production' }
};

// For React components with spread props:
interface BaseProps {
  children: React.ReactNode;
}

type DivProps = BaseProps & React.HTMLAttributes<HTMLDivElement>;

const Container = (props: DivProps) => {
  // Can spread all div attributes including className, style, etc.
  return <div {...props}>{props.children}</div>;
};
5Configure tsconfig.json to suppress excess property errors

For legacy codebases or specific cases, you can disable excess property checking:

json
// tsconfig.json
{
  "compilerOptions": {
    "suppressExcessPropertyErrors": true
  }
}

WARNING: This disables ALL excess property checking globally. Use only as a last resort.

Better approach: Use a more targeted solution with interface merging or utility types:

typescript
// Use Partial for optional configurations
interface RequiredConfig {
  apiUrl: string;
  timeout: number;
}

type Config = RequiredConfig & Partial<{
  retries: number;
  debug: boolean;
  cache: boolean;
}>;

// Now all are optional extras
const config: Config = {
  apiUrl: '/api',
  timeout: 5000,
  retries: 3, // No error
  debug: true // No error
};

// Use Omit to remove strictness from specific functions
interface User {
  id: string;
  name: string;
  age: number;
}

function updateUser(id: string, updates: Partial<Omit<User, 'id'>>) {
  // Can accept any subset of User properties except 'id'
}

updateUser('123', { name: 'John', extraField: 'value' }); // Error on extraField

// Make it more permissive:
function updateUser(id: string, updates: Partial<Omit<User, 'id'>> & Record<string, any>) {
  // Now accepts extra properties
}
6Use utility types for flexible object shapes

TypeScript's utility types can help create more flexible interfaces:

typescript
// Use intersection types to combine required and optional properties
interface RequiredFields {
  name: string;
  age: number;
}

interface OptionalFields {
  email?: string;
  phone?: string;
  address?: string;
}

type User = RequiredFields & OptionalFields & Record<string, any>;

// Now User accepts any extra properties
const user: User = {
  name: 'John',
  age: 30,
  email: 'john@example.com',
  customField: 'value' // Allowed due to Record<string, any>
};

// For API responses that may include metadata:
type ApiResponse<T> = {
  data: T;
  success: boolean;
  timestamp: string;
} & Record<string, any>;

interface Product {
  id: string;
  name: string;
  price: number;
}

const response: ApiResponse<Product> = {
  data: { id: '1', name: 'Widget', price: 9.99 },
  success: true,
  timestamp: '2024-01-01',
  metadata: { page: 1, total: 100 }, // Extra properties allowed
  debug: true // Also allowed
};

// Use generics for maximum flexibility
function createConfig<T extends Record<string, any>>(base: T, extras: Record<string, any>) {
  return { ...base, ...extras };
}

const config = createConfig(
  { apiUrl: '/api', timeout: 5000 },
  { retries: 3, debug: true } // No type errors
);

Advanced notes

### Understanding Excess Property Checking

TypeScript's excess property checking is a form of "freshness" checking that applies only to object literals. When you create an object literal, TypeScript considers it "fresh" and checks it more strictly than an object that comes from a variable.

Key concepts:
1. Fresh objects: Object literals get strict checking
2. Stale objects: Variables/parameters get structural checking
3. Type compatibility: TypeScript uses structural typing (duck typing), but fresh objects have extra rules

### When Excess Property Checking Applies

The check triggers when:
1. Assigning an object literal to a variable with a type annotation
2. Passing an object literal as an argument to a function
3. Returning an object literal from a function with a return type annotation
4. Using object literals in JSX/TSX props

### Bypassing Strategies

1. Type assertions: as Type or <Type>{...}
2. Intermediate variables: Assign to variable first
3. Index signatures: [key: string]: any
4. Utility types: Partial<T> & Record<string, any>
5. tsconfig option: "suppressExcessPropertyErrors": true (not recommended)

### React/JSX Specifics

In React, excess property checking helps catch prop typos:

typescript
interface ButtonProps {
  onClick: () => void;
  children: React.ReactNode;
}

// ERROR: 'onclick' (lowercase) doesn't exist
<Button onclick={() => {}}>Click me</Button>

// Common React patterns:
// 1. Spread operator for HTML attributes
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string;
}

// 2. Component props with rest parameters
function Card({ title, children, ...rest }: CardProps & React.HTMLAttributes<HTMLDivElement>) {
  return <div {...rest}><h2>{title}</h2>{children}</div>;
}

### Performance Considerations

Excess property checking happens at compile time and has no runtime impact. However, using index signatures ([key: string]: any) can reduce type safety. Consider more precise alternatives:

typescript
// Instead of:
interface LooseConfig {
  [key: string]: any;
}

// Use:
interface TypedConfig {
  required: string;
  optional?: Record<string, string | number | boolean>;
  metadata?: {
    [K in 'created' | 'modified' | 'version']?: string;
  };
}

### Testing and Validation

When testing functions that accept object parameters, consider:
1. Creating test data factories that return typed objects
2. Using satisfies operator for inline objects that should match a type
3. Creating helper types for test data that include extra properties

typescript
// Using 'satisfies' for test objects
const testUser = {
  name: 'Test',
  age: 25,
  testId: 123  // Extra property for testing
} satisfies User;  // Still type-checks against User

// Test data factory
function createTestUser(overrides?: Partial<User> & Record<string, any>): User & { testId: number } {
  return {
    name: 'Test',
    age: 25,
    testId: Date.now(),
    ...overrides,
  };
}

Frequently asked questions

What does "Object literal may only specify known properties, and 'name' does not" mean?
The "Object literal may only specify known properties" error is TypeScript's way of enforcing strict type checking when you create object literals. This is part of TypeScript's excess property checking feature, which helps catch common bugs like typos in property names or accidentally passing extra data. When you pass an object literal directly to a function or assign it to a variable with a specific type, TypeScript performs extra validation beyond normal type compatibility.
How do I fix "Object literal may only specify known properties, and 'name' does not"?
TS2353 fires when an object literal has a property not in the target type. Fix the typo, widen the type, or assert with 'as'.
What causes "Object literal may only specify known properties, and 'name' does not"?
Passing an object literal with extra properties to a typed parameter Typo in property name (e.g., 'colour' instead of 'color') Using deprecated property names that were removed from the type
Is the "Object literal may only specify known properties, and 'name' does not" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading