'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 1:[1]

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;
    ...;
};

Solution 2:[2]

You can create a helper type and use is like this:

// Helper type
export type RequiredField<T, K extends keyof T> = T & Required<Pick<T, K>>;


// Use
RequiredField<IUser, 'role'>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Dat V.