TypeScript Required<T> Utility Type Explained
Learn how Required<T> makes all properties of a type required, the opposite of Partial<T>. Includes syntax, examples, and use cases for strict type enforcement.
Detailed Explanation
Understanding Required
Required<T> constructs a type with all properties of T set to required. It is the inverse of Partial<T>, removing the optional modifier (?) from every property.
Syntax
type Required<T> = {
[P in keyof T]-?: T[P];
};
The -? syntax removes the optional modifier. This is a lesser-known TypeScript feature called a "mapping modifier removal."
Basic Example
interface Config {
host?: string;
port?: number;
debug?: boolean;
timeout?: number;
}
type StrictConfig = Required<Config>;
// Equivalent to:
// {
// host: string;
// port: number;
// debug: boolean;
// timeout: number;
// }
Practical Pattern: Validated Configuration
A common pattern is accepting a partial config from the user, applying defaults, and then treating the result as a fully required type:
const defaults: Required<Config> = {
host: "localhost",
port: 3000,
debug: false,
timeout: 5000,
};
function createApp(userConfig: Config): App {
const config: Required<Config> = { ...defaults, ...userConfig };
// All fields are guaranteed to exist
console.log(config.host); // string, not string | undefined
return new App(config);
}
Combining with Pick
You can use Required with Pick to make only specific properties required:
type WithRequiredId = Partial<User> & Required<Pick<User, "id">>;
// id is required, everything else is optional
Use Case
Use Required<T> when you have validated or defaulted all optional properties and need a strict type where every field is guaranteed to exist. Common in configuration resolution, form validation results, and post-initialization state types.