Guest User

Untitled

a guest
Apr 26th, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. import { Maybe } from 'true-myth';
  2.  
  3. // `OptionalField`, `RequiredField` are just input fields which know how to
  4. // handle optionality on the field. `InputTypes` => `string | number | boolean`.
  5. import Field, { OptionalField, RequiredField, InputTypes } from './field';
  6. import { NonNullableFieldNames } from './type-utils';
  7.  
  8. /**
  9. Map the fields on an type to a new type whose type values are:
  10. - `OptionalField<T>` if the original type is a `Maybe<T>` or an optional `T`
  11. (i.e. `field?: T`) if `T` belongs to `InputTypes`
  12. - `RequiredField<T>` if the original type is simply `T` and `T` belongs to
  13. `InputTypes`
  14. - `never` for all other fields
  15. where `InputTypes` is `boolean | number | string`.
  16. For example, given a `User` type defined like this:
  17. ```ts
  18. type User = {
  19. age: number;
  20. name?: string;
  21. description: Maybe<string>;
  22. attributes: string[];
  23. };
  24. ```
  25. Then `Fields<User>` has the type:
  26. ```ts
  27. type Fields<User> = {
  28. age: RequiredField<number>;
  29. name: OptionalField<string>;
  30. description: OptionalField<String>;
  31. attributes: never;
  32. }
  33. ```
  34. */
  35. export type Fields<T> = Required<
  36. {
  37. [K in keyof T]: K extends NonNullableFieldNames<T>
  38. ? T[K] extends Maybe<infer U>
  39. ? U extends InputTypes ? OptionalField<U> : never
  40. : T[K] extends infer V ? (V extends InputTypes ? RequiredField<V> : never) : never
  41. : T[K] extends infer W ? (W extends InputTypes ? OptionalField<W> : never) : never
  42. }
  43. >;
  44.  
  45. /**
  46. Get the property names for only the properties whose types are not marked as
  47. `never` by `Fields`. Used in conjunction with `ValidFields`.
  48. */
  49. export type ValidFieldNames<T> = { [K in keyof T]: T[K] extends never ? never : K }[keyof T];
  50.  
  51. /**
  52. Using the set of property names for non-`never` types given by
  53. `ValidFieldNames`, create a mapped type consisting of the fields in `Fields`
  54. whose original types in a model are all in `InputTypes`. Not useful unless the
  55. type parameter is `Fields`.
  56. */
  57. export type ValidFields<T> = Pick<T, ValidFieldNames<T>>;
  58.  
  59. /**
  60. Given a backing/persistence model, define the type of a corresponding form
  61. model.
  62.  
  63. Optional fields and fields defined with the True Myth `Maybe` type are mapped
  64. to the `OptionalField` type. Non-optional fields are mapped to the
  65. `RequiredField` type.
  66.  
  67. For example, given a `User` model from the persistence layer, defined
  68. so:
  69.  
  70. ```ts
  71. export type User = {
  72. age: number;
  73. name?: string;
  74. description: Maybe<string>;
  75. attributes: string[];
  76. };
  77. ```
  78.  
  79. The type `Form<User>` is:
  80.  
  81. ```ts
  82. type Form<User> = {
  83. age: RequiredField<number>;
  84. name: OptionalField<string>;
  85. description: OptionalField<string>;
  86. }
  87. ```
  88. */
  89. export type Form<T> = ValidFields<Fields<T>>;
  90.  
  91. type User = {
  92. age: number;
  93. name?: string;
  94. familyName: Maybe<string>;
  95. };
  96.  
  97. // Has the type:
  98. //
  99. // ```
  100. // type UserForm = {
  101. // age: RequiredField<number>;
  102. // name: OptionalField<string>;
  103. // familyName: OptionalField<string>;
  104. // }
  105. // ```
  106. type UserForm = Form<User>;
Add Comment
Please, Sign In to add comment