Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Maybe } from 'true-myth';
- // `OptionalField`, `RequiredField` are just input fields which know how to
- // handle optionality on the field. `InputTypes` => `string | number | boolean`.
- import Field, { OptionalField, RequiredField, InputTypes } from './field';
- import { NonNullableFieldNames } from './type-utils';
- /**
- Map the fields on an type to a new type whose type values are:
- - `OptionalField<T>` if the original type is a `Maybe<T>` or an optional `T`
- (i.e. `field?: T`) if `T` belongs to `InputTypes`
- - `RequiredField<T>` if the original type is simply `T` and `T` belongs to
- `InputTypes`
- - `never` for all other fields
- where `InputTypes` is `boolean | number | string`.
- For example, given a `User` type defined like this:
- ```ts
- type User = {
- age: number;
- name?: string;
- description: Maybe<string>;
- attributes: string[];
- };
- ```
- Then `Fields<User>` has the type:
- ```ts
- type Fields<User> = {
- age: RequiredField<number>;
- name: OptionalField<string>;
- description: OptionalField<String>;
- attributes: never;
- }
- ```
- */
- export type Fields<T> = Required<
- {
- [K in keyof T]: K extends NonNullableFieldNames<T>
- ? T[K] extends Maybe<infer U>
- ? U extends InputTypes ? OptionalField<U> : never
- : T[K] extends infer V ? (V extends InputTypes ? RequiredField<V> : never) : never
- : T[K] extends infer W ? (W extends InputTypes ? OptionalField<W> : never) : never
- }
- >;
- /**
- Get the property names for only the properties whose types are not marked as
- `never` by `Fields`. Used in conjunction with `ValidFields`.
- */
- export type ValidFieldNames<T> = { [K in keyof T]: T[K] extends never ? never : K }[keyof T];
- /**
- Using the set of property names for non-`never` types given by
- `ValidFieldNames`, create a mapped type consisting of the fields in `Fields`
- whose original types in a model are all in `InputTypes`. Not useful unless the
- type parameter is `Fields`.
- */
- export type ValidFields<T> = Pick<T, ValidFieldNames<T>>;
- /**
- Given a backing/persistence model, define the type of a corresponding form
- model.
- Optional fields and fields defined with the True Myth `Maybe` type are mapped
- to the `OptionalField` type. Non-optional fields are mapped to the
- `RequiredField` type.
- For example, given a `User` model from the persistence layer, defined
- so:
- ```ts
- export type User = {
- age: number;
- name?: string;
- description: Maybe<string>;
- attributes: string[];
- };
- ```
- The type `Form<User>` is:
- ```ts
- type Form<User> = {
- age: RequiredField<number>;
- name: OptionalField<string>;
- description: OptionalField<string>;
- }
- ```
- */
- export type Form<T> = ValidFields<Fields<T>>;
- type User = {
- age: number;
- name?: string;
- familyName: Maybe<string>;
- };
- // Has the type:
- //
- // ```
- // type UserForm = {
- // age: RequiredField<number>;
- // name: OptionalField<string>;
- // familyName: OptionalField<string>;
- // }
- // ```
- type UserForm = Form<User>;
Add Comment
Please, Sign In to add comment