I'm trying to get the compiler to help me with validation of payloads received over the network. So what I want to do is take a JSON payload over the wire and make sure the compiler complains if all the fields are not set. I know the way to do this is to use validation functions but even before I get to the validation part I need to generate some boilerplate that converts a type with nullable fields into a type with strict fields. So the validation functions must have the following signature
type Validator<T> = (i: T) => Strictify<T>;
The problem is that I don't know how to get Strictify
to actually work. When I write the following it doesn't work
type Strictify<T> = {
[K in keyof T]: Exclude<T[K], undefined>
};
type Test = { k?: string };
type StrictTest = Strictify<Test>;
The type of StrictTest
should be { k: string }
but it's actually still { k?: string }
. The interesting part is if I change the definition of Test
to { k: string | undefined }
then it works. The strictified type is what I expect it to be. Anyone know how to make this all work without expanding every k?: T
to k: T | undefined
?
Your version would work if the field type were to have been declared as string|undefined
. Although under strictNullChecks
optional fields are shown as having the type string|undefined
they are not the same thing, optionality is a property of the field.
To remove the optional modifier from the field when using a homomorphic mapped type, starting in typescript 2.8, you can add -?
to the type:
type Strictify<T> = {
[K in keyof T]-?: Exclude<T[K], undefined>
};
type Test = { k?: string };
type StrictTest = Strictify<Test>;