TypeScript has a Partial
type defined by default, so that you can say Partial<{x: number, y: string}>
to get a type like {x?: number, y?: string}
(the type's properties become optional). It is defined as
type Partial<T> = {
[P in keyof T]?: T[P]
}
I am trying to define the inverse, let's call it Full<T>
, which makes sure all properties in the object are required. I started with the obvious definition:
type Full<T> = {
[P in keyof T]: T[P]
}
Which is just Partial
with the question mark removed. Unfortunately, this doesn't work—optional properties remain optional. It seems typescript somehow, in some circumstances, preserves information about the requiredness of the property names in the keyof
type.
Interestingly, if you store that type in an intermediate type name, that information is dropped. I.e. this works:
type Config = {foo: number, bar?: string}
type ConfigKey = keyof Config
type FullConfig = {[K in ConfigKey]: Config[K]}
In FullConfig
(at least with TypeScript 3.3), bar
is required. But if you inline keyof Config
into the definition of FullConfig
, it is optional again.
I'd like this to be a single, easy-to-use type, and since I'm not aware of a way for a type declaration to define local types, this hack doesn't seem to help much there.
Is there any trick I'm missing?
Mapped types are not all created equal. Homomorphic mapped types preserve modifiers of the mapped type. From the pull request introducing this feature:
With this PR we preserve property modifiers in homomorphic (structure preserving) mapped types. A mapped type of the form
{ [P in keyof T]: X }
is homomorphic withT
(because it has the same set of properties asT
) and now preserves the optional and readonly modifiers as they exist on the properties inT
.
Starting from 2.8 you can remove modifiers from such types using a -
(see PR) :
type Full<T> = {
[P in keyof T]-?: T[P];
}
Note
You can use the predefined Required
type from the standard library which does the exact same thing as Full
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With