typescripttypescript-genericsrequired-field

How can I make one property non-optional in a TypeScript type?


I have this type:

type User = { 
  id: string;
  name?: string;
  email?: string;
}

And I would like to construct a similar type with name non optional:

type UserWithName = {
  id: string;
  name: string;
  email?: string;
}

Instead of repeating the type as I did above, how can I construct UserWithName from User with generic utility types?
Required almost does the job but it sets all properties as non-optional, while I just want to set one property.


Solution

  • If you check the source for the Required type, it's this:

    type Required<T> = {
      [P in keyof T]-?: T[P]
    }
    

    The same syntax can be used to construct a generic type that will give you what you want:

    type User = {
      id: string
      name?: string
      email?: string
    }
    
    type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] }
    
    type UserWithName = WithRequired<User, 'name'>
    
    // error: missing name
    const user: UserWithName = {
      id: '12345',
    }
    

    Playground link