Suggest an editImprove this articleRefine the answer for “Utility type required in TypeScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Required<T>** is a TypeScript utility type that removes `?` from every optional property in `T`, making all fields required. ```ts interface User { name?: string; age?: number; } type StrictUser = Required<User>; // { name: string; age: number; } ``` **Key point:** Opposite of `Partial<T>`. Compile-time only, no runtime effect.Shown above the full answer for quick recall.Answer (EN)Image**Required<T>** is a TypeScript utility type that strips the `?` from every optional property in `T`, making all of them required at compile time. ## Theory ### TL;DR - Think of a form where all fields were optional, then someone stamped "fill in everything" on each one - Main difference: removes `?` from each property but keeps the type (`string | undefined` does NOT become `string | undefined` - it becomes just `string`) - Use after validation when you know all fields are present; keep `Partial<T>` while building the object - Compile-time only - no runtime effect - Opposite of `Partial<T>` ### Quick example ```ts interface User { name: string; age?: number; // optional } type StrictUser = Required<User>; const user: StrictUser = { name: "Alice", age: 30 }; // works // const bad: StrictUser = { name: "Bob" }; // Error: age is missing ``` `StrictUser` now demands both `name` and `age`. Skip either one and TypeScript complains immediately. ### Key difference `Required<T>` only removes the `?` modifier - it does not keep `undefined` in the type. So `age?: number` becomes `age: number`, not `age: number | undefined`. That matters when you write functions expecting a guaranteed value and want TypeScript to catch omissions at compile time, not at runtime. ### When to use - Data collected as `Partial<T>`, then validated: use `Required<T>` as the return type of your validation function - API response after a successful request: you know the shape is complete - React component props with all defaults applied: pass `Required<Props>` to child components - Generating mock data: avoids unexpected `undefined` crashes in tests - After a type guard confirmed all fields exist: `data is Required<FormData>` reads cleanly ### How the compiler handles this TypeScript maps over every property descriptor in `T`. For each one marked as optional, it rewrites the descriptor to required. Under the hood this is a mapped type: `{ [K in keyof T]-?: T[K] }`. The `-?` syntax strips the optional modifier. No JavaScript is emitted - purely a compile-time transformation. ### Common mistakes **1. Expecting runtime enforcement** ```ts // Required<T> does NOT check values at runtime const data = JSON.parse(response) as Required<User>; // bypasses all checks ``` TypeScript trusts the cast. Pair `Required<T>` with an actual type guard or a schema validator like Zod if you need runtime safety. **2. Thinking it handles nested optionals** The shallow behavior catches almost everyone the first time. You apply `Required<T>` expecting full coverage, then spend an hour debugging `undefined` three levels deep in a config object. ```ts type Nested = Required<{ a?: { b?: string } }>; // Result: { a: { b?: string } } // a is required, but b inside is still optional ``` For deep nesting, write a recursive type: ```ts type DeepRequired<T> = T extends object ? { [K in keyof T]-?: DeepRequired<T[K]> } : T; ``` **3. Applying it to union types** ```ts type Bad = Required<string | { a?: number }>; // Resolves unexpectedly - avoid Required on union types directly ``` If your type is a union, apply `Required` to each member separately or use `Extract` first. **4. Using it on primitives** `Required<string>` returns `string` unchanged. There is nothing to strip. ### Real-world usage - **React form handler**: `validateForm(data: FormData): data is Required<FormData>` - type guard after checking all fields - **Express middleware**: `Request<{}, {}, Required<CreateUserBody>>` after body validation - **React Query**: `Required<Omit<Response, 'data'>>` on the success path - **Zod**: `z.infer<typeof schema> & Required<PartialFields>` for partial schemas - **TanStack Table**: column def merging with `Required<Partial<ColumnDef>>` ### Follow-up questions **Q:** What is the type of `Required<{ a?: string }>`? **A:** `{ a: string }`. The `?` is removed and the type stays `string`, not `string | undefined`. **Q:** Does `Required<T>` affect nested objects? **A:** No. It only removes `?` from top-level properties. Nested optional fields stay optional. Use a custom `DeepRequired<T>` for that. **Q:** What is the difference between `Required<T>` and `Omit<T, never>`? **A:** Same structural result, but `Required<T>` is the semantic choice. `Omit<T, never>` is a workaround and fails on non-object types. **Q:** How do you make `Required` apply only to specific keys? **A:** `type RequiredSpecific<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>`. This targets only the keys you name, leaving the rest untouched. **Q:** Why does `-?` appear in mapped types? **A:** It is a modifier syntax. `+?` adds the optional flag, `-?` strips it. `Required<T>` uses `{ [K in keyof T]-?: T[K] }` internally. ## Examples ### Basic: making optional fields required ```ts interface Product { id: number; name: string; description?: string; price?: number; } type FullProduct = Required<Product>; const item: FullProduct = { id: 1, name: "Keyboard", description: "Mechanical", // now required price: 99, // now required }; // const broken: FullProduct = { id: 1, name: "Mouse" }; // Error: missing fields ``` Before `Required<T>`, you could create a `Product` without `description` or `price`. After, TypeScript blocks it at the type level. ### Intermediate: form validation with a type guard ```ts interface FormData { email: string; phone?: string; address?: string; } function validateForm(data: FormData): data is Required<FormData> { return !!data.phone && !!data.address; } function submitUser(formData: FormData) { if (validateForm(formData)) { // TypeScript knows all fields are present inside this block console.log(`${formData.email} - ${formData.phone} - ${formData.address}`); } } const data: FormData = { email: "user@example.com", phone: "555-1234", address: "10 Main St", }; submitUser(data); ``` The type guard `data is Required<FormData>` narrows the type inside the `if` block. No casting needed. This pattern appears often in Next.js API routes after collecting and checking form input.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.