Search code examples
typescripttypescript-typings

How to make some fields in object required


I need an interface for making some fields of other interface as required. For example: I have IUserInterface:

interface IUser {
  name: string;
  role?: string;
}

interface IUserFromDB {
  id: number;
  name: string;
  role: string;
}

When I create new user - role is optional. DB set default role and when I select user from DB - role must be in userObject. I can write Interfaces like I've written above, but in a real project this approach creates a lot of redundant code. So, I need some interface, that help me to get old interface and make some optional fields as required.

I want something like this:

interface IUser {
  name: string;
  role?: string;
}

type IUserFromDB = WithRequired<IUser, 'role'[|...]> & {
  id: number;
  ...;
};

Please help me to create this WithRequired type.


Solution

  • Keeping your IUser interface

    Using Partial, Pick, and Required:

    interface IUser {
        name: string;
        role?: string;
    }
    
    type IUserFromDB = Partial<IUser> & Required<Pick<IUser, 'name' | 'role'>> & {
        id: number;
        ...;
    };
    
    

    In this case the use of Partial is not required unless IUser grows. As it does not affect in run time, I suggest to keep it anyway :)

    Alternative approach

    With a common fully-required model and using Partial and Pick for any derived type:

    interface IUserModel {
        name: string;
        role: string;
    }
    
    type IUser = Partial<IUserModel> & Pick<IUserModel, 'name'>; 
    
    type IUserFromDB = Partial<IUserModel> & Pick<IUserModel, 'name' | 'role'> & {
        id: number;
        ...;
    };