RequireSome type from another, very simialar question. This question is similar but it should not be a duplicate since here we want to also remove null as well as undefined from properties.
Maybe the name shouldn't be Require but something like NonNullable or of this kind. The goal of this type is to specify which fields from a type should not be undefined or null, and return their types without undefined and null.
type Question = {
id: string;
answer?: string | null;
thirdProp?: number | null;
fourthProp?: number | null;
}
// usage NonNullable<Question, 'answer' | 'thirdProp'> expect to equal
/*
type Question = {
id: string; // no changes
answer: string; // changed
thirdProp: number; // changed
fourthProp?: number | null; // no changes
}
*/
The simplified approach that just intersects with T
with Required<Pick<T, K>>
with the required part basically overriding the optional properties in T
will not work here. (Incidentally this works because { foo?: X } & { foo: X }
is essentially { foo: X }
)
To also remove nullability, we have to first create a type that removed null
and undefined
from a given type T
(analogous to Required
). Then we need to intersect the properties we want to make required and not null with the rest of the keys in T
using the Omit
type.
type Omit<T, K> = Pick<T, Exclude<keyof T, K>> // not needed in ts 3.5
type RequiredAndNotNull<T> = {
[P in keyof T]-?: Exclude<T[P], null | undefined>
}
type RequireAndNotNullSome<T, K extends keyof T> =
RequiredAndNotNull<Pick<T, K>> & Omit<T, K>
type Question = {
id: string;
answer?: string | null;
thirdProp?: number | null;
fourthProp?: number | null;
}
type T0 = RequireAndNotNullSome<Question, 'answer' | 'thirdProp'>