Reputation: 987
If I have a type with all required properties, how can I define another type with the same properties where some of it's properties are still required but the rest are optional?
For example I want a new type derived from SomeType where prop1 and prop2 are required but the rest are optional:
interface SomeType {
prop1;
prop2;
prop3;
...
propn;
}
interface NewType {
prop1;
prop2;
prop3?;
...
propn?;
}
Upvotes: 33
Views: 32796
Reputation: 2364
Here is another way
export type ContactInfoFormInput = Pick<AccountDetails, 'email' | 'phone'> &
Pick<Profile, 'firstName' | 'lastName'> & {
dateCreated?: Profile['dateCreated'];
};
So in this example, email, phone, firstName, lastName are all required but dateCreated which also comes from the Profile base type is optional
Upvotes: 0
Reputation: 1696
From this article:
We can derive the following type:
export type PartialPick<T, F extends keyof T> = Omit<T, F> & Partial<Pick<T, F>>;
F - the fields that should be made optional
T - the type
In your example:
type NewType = PartialPick<SomeType, 'prop3' | ... | 'propn'>
If you'd like to make some properties required instead of the partial use:
type RequiredPick<T, F extends keyof T> = Omit<T, F> & Required<Pick<T, F>>;
If NewType should be an interface and has additional fields besides the fields in SomeType, you can use extends from the type:
interface SomeType {
prop1;
prop2;
prop3;
prop4;
}
interface NewType extends PartialPick<SomeType, 'prop3' | 'prop4'> {
prop5;
}
Upvotes: 4
Reputation: 1440
type onlyOneRequired = Partial<Tag> & {id: string}
In the above type, all properties of Tag are optional instead of id
which is required.
So you can use this method and specify the required properties.
Upvotes: 6
Reputation: 445
For tetter performance, in addition to Titian's answer, you must do :
type OptionalExceptFor<T, TRequired extends keyof T = keyof T> = Partial<
Pick<T, Exclude<keyof T, TRequired>>
> &
Required<Pick<T, TRequired>>;
Upvotes: 5
Reputation: 250306
You can use combination of Partial
and Pick
to make all properties partial and then pick only some that are required:
interface SomeType {
prop1: string;
prop2: string;
prop3: string;
propn: string;
}
type OptionalExceptFor<T, TRequired extends keyof T> = Partial<T> & Pick<T, TRequired>
type NewType = OptionalExceptFor<SomeType, 'prop1' | 'prop2'>
let o : NewType = {
prop1: "",
prop2: ""
}
Upvotes: 69