← Back to TypeScript Course | Chapter 8: Advanced Types | Lesson 11 of 20

Utility Types - Required

Required<T> makes every property of an object type required. It is useful when a type contains optional properties but a particular operation needs all of them.

Basic Required

Required<T> converts every optional property of T into a required one, which is effectively the exact opposite transformation of the Partial<T> utility type.

Example: Basic Required

typescript
interface Todo {
  title?: string;
  done?: boolean;
}
type CompleteTodo = Required<Todo>;
const t: CompleteTodo = { title: "Buy milk", done: false };
console.log(t);

Required for Complete Objects

Required is useful when a function expects an object that has already been fully configured, ensuring at compile time that no optional field was accidentally left unset before that point in the code.

Example: Required for Complete Objects

typescript
interface Config {
  host?: string;
  port?: number;
}
function start(config: Required<Config>) {
  console.log(`Starting on ${config.host}:${config.port}`);
}
start({ host: "localhost", port: 8080 });

Required Preserves Types

Required changes only the optionality of each property, not its underlying type — a property that was string | undefined and optional becomes a required string | undefined, not a required plain string.

Example: Required Preserves Types

typescript
interface Profile {
  bio?: string | undefined;
}
type FullProfile = Required<Profile>;
const p: FullProfile = { bio: undefined };
console.log(p);

Required with Interfaces

Required can be applied to interface types in exactly the same way it applies to object type aliases, since both describe object shapes that Required can transform identically.

Example: Required with Interfaces

typescript
interface Draft {
  title?: string;
  body?: string;
}
const finalPost: Required<Draft> = { title: "Hello", body: "World" };
console.log(finalPost);

When to Use Required

Use Required when a later stage of your application logically needs every property that an earlier, more permissive stage had left optional, such as after a form has been fully validated.

Example: When to Use Required

typescript
interface FormState {
  name?: string;
  email?: string;
}
function submit(data: Required<FormState>) {
  console.log("Submitting", data);
}
submit({ name: "Ravi", email: "[email protected]" });

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.