Created
September 20, 2023 17:34
-
-
Save pmn4/60704329a62232af57ac4aa51bfe6fd7 to your computer and use it in GitHub Desktop.
TypeScript: Deserialized
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| TypeScript can struggle with deserialization. Reading from localStorage, | |
| dealing with user input, or receiving data from an API are all cases where the | |
| data coming in may not have the EXACT type we want it to have. Dates are a | |
| perfect example, in that they are typically serialized as a string, which | |
| makes deserializing them impossible since we cannot distinguish between a | |
| string that is intended to be a Date and one that is intended to be the string | |
| representation of a date. | |
| Hence, the Deserialized type: | |
| */ | |
| type Primitive = string | number | boolean | symbol; | |
| // add any primitive-like imported types here, e.g., Decimal | |
| type SerializedAsString = bigint | Date; | |
| export type Deserialized<T> = T extends Array<infer A> | |
| ? Deserialized<A>[] | |
| : T extends Primitive | null | undefined | |
| ? T | |
| : T extends SerializedAsString | null | undefined | |
| ? ApplyOptionality<T, string> | |
| : { [K in keyof T]: Deserialized<T[K]> }; | |
| // maintain any optionality (null or undefined or both) from source to destination | |
| type ApplyOptionality<From, To> = To | (From & null) | (From & undefined); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Given some object that a client might send in a POST request:
the server would receive a serialization of that object, and parse it, e.g.,:
so we cast it as a deserialized version of the intended type:
and now we've got type safety!: