DEV Community

Benjamin Arambide
Benjamin Arambide

Posted on

Typing Objects with at Least One Property in TypeScript

In TypeScript, there are cases where you want to define a type that ensures an object contains at least one specific property, while allowing any additional properties.

A common example is ensuring an object has a name property, regardless of what else it contains.

Basic Use Case

To specify that an object must have at least a name property:

interface HasName {
  name: string;
}

function greet(obj: HasName) {
  console.log(`Hello, ${obj.name}`);
}

greet({ name: "Alice", age: 30 }); // ✅ Works
Enter fullscreen mode Exit fullscreen mode

Using Inline Types

Instead of declaring a separate interface:

function greet(obj: { name: string }) {
  console.log(`Hi, ${obj.name}`);
}
Enter fullscreen mode Exit fullscreen mode

This also works fine for inline use.

Using Generics with Constraints

If you're working with generics and want to retain the full object type while requiring a name property:

function greet<T extends { name: string }>(obj: T) {
  console.log(`Hi, ${obj.name}`);
}
Enter fullscreen mode Exit fullscreen mode

This keeps the full shape of the passed object available for further use.

Dynamic Check with Type Predicate

Sometimes you receive unknown data and want to ensure it has a name property:

function hasName(obj: any): obj is { name: string } {
  return typeof obj === 'object' && obj !== null && 'name' in obj;
}
Enter fullscreen mode Exit fullscreen mode

Used like:

const data = { name: "Bob", age: 40 };

if (hasName(data)) {
  console.log(data.name); // Safe access
}
Enter fullscreen mode Exit fullscreen mode

Summary

To enforce the presence of a property like name:

  • ✅ Use a basic interface like { name: string }
  • ✅ Use generics for flexibility and type retention
  • ✅ Use type predicates for runtime checks
  • 🔐 TypeScript won't automatically enforce "only one property", but it ensures required keys exist

This pattern is useful in APIs, forms, and anywhere you want to enforce structure while still allowing flexibility.

Top comments (1)

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

This doesn't work:

interface HasName {
  name: string;
}

function greet(obj: HasName) {
  console.log(`Hello, ${obj.name}`);
}

greet({ name: "Alice", age: 30 });
Enter fullscreen mode Exit fullscreen mode

TypeScript throws the following error:

Object literal may only specify known properties, and 'age' does not exist in type 'HasName'.(2353)
(property) age: number
Enter fullscreen mode Exit fullscreen mode

The inline typing also doesn't work; it throws the same error.