inferred-types 0.15.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/.tsbuildinfo +1 -0
  2. package/devops/build.js +1 -3
  3. package/dist/{types/utility/state/KeyStorage.d.ts → index.d.ts} +9767 -8195
  4. package/dist/index.js +659 -0
  5. package/dist/index.mjs +577 -0
  6. package/on-hold/tests/api-spec.ts +9 -15
  7. package/package.json +27 -37
  8. package/pnpm-lock.yaml +2385 -2117
  9. package/src/errors/InferenceError.ts +1 -1
  10. package/src/shared/randomString.ts +1 -1
  11. package/src/types/Constructor.ts +5 -0
  12. package/src/types/Not.ts +3 -1
  13. package/src/types/Transformer.ts +1 -2
  14. package/src/types/Where.ts +36 -0
  15. package/src/types/alphabetic/PascalCase.ts +5 -4
  16. package/src/types/alphabetic/index.ts +9 -5
  17. package/src/types/{fluent.ts → fluent/fluent.ts} +8 -9
  18. package/src/types/fluent/index.ts +42 -0
  19. package/src/types/index.ts +13 -7
  20. package/src/types/lists/UniqueForProp.ts +13 -3
  21. package/src/types/ruleset-types.ts +1 -1
  22. package/src/types/{SameKeys.ts → type-conversion/SameKeys.ts} +0 -0
  23. package/src/types/type-conversion/WrapValue.ts +15 -0
  24. package/src/types/type-conversion/index.ts +11 -4
  25. package/src/utility/dictionary/arrayToKeyLookup.ts +3 -4
  26. package/src/utility/dictionary/dictionaryTransform.ts +6 -7
  27. package/src/utility/index.ts +3 -2
  28. package/src/utility/lists/groupBy.ts +22 -0
  29. package/src/utility/lists/index.ts +38 -0
  30. package/tests/Where.spec.ts +39 -0
  31. package/tests/constructor.spec.ts +40 -0
  32. package/tests/data/index.ts +8 -3
  33. package/tests/kv/dict-to-kv-and-back.spec.ts +2 -6
  34. package/tsconfig.json +4 -3
  35. package/dist/cjs/index.js +0 -21
  36. package/dist/es/index.js +0 -17
  37. package/dist/tsconfig.tsbuildinfo +0 -1
  38. package/dist/types/Mutation/MutationFunction.d.ts +0 -16
  39. package/dist/types/Mutation/MutationIdentity.d.ts +0 -30
  40. package/dist/types/Mutation/index.d.ts +0 -2
  41. package/dist/types/errors/InferenceError.d.ts +0 -1
  42. package/dist/types/errors/index.d.ts +0 -1
  43. package/dist/types/index.d.ts +0 -4
  44. package/dist/types/shared/index.d.ts +0 -3
  45. package/dist/types/shared/randomString.d.ts +0 -1
  46. package/dist/types/shared/uuid.d.ts +0 -1
  47. package/dist/types/shared/valueTypes.d.ts +0 -27
  48. package/dist/types/types/Api.d.ts +0 -10
  49. package/dist/types/types/EnumValues.d.ts +0 -14
  50. package/dist/types/types/ExpandRecursively.d.ts +0 -3
  51. package/dist/types/types/First.d.ts +0 -4
  52. package/dist/types/types/FunctionType.d.ts +0 -9
  53. package/dist/types/types/If.d.ts +0 -10
  54. package/dist/types/types/Include.d.ts +0 -16
  55. package/dist/types/types/Includes.d.ts +0 -5
  56. package/dist/types/types/KeyedRecord.d.ts +0 -22
  57. package/dist/types/types/Keys.d.ts +0 -17
  58. package/dist/types/types/Length.d.ts +0 -8
  59. package/dist/types/types/Mutable.d.ts +0 -6
  60. package/dist/types/types/Narrowable.d.ts +0 -5
  61. package/dist/types/types/Not.d.ts +0 -11
  62. package/dist/types/types/Numeric.d.ts +0 -14
  63. package/dist/types/types/Opaque.d.ts +0 -12
  64. package/dist/types/types/Retain.d.ts +0 -16
  65. package/dist/types/types/SameKeys.d.ts +0 -11
  66. package/dist/types/types/Transformer.d.ts +0 -11
  67. package/dist/types/types/TypeGuard.d.ts +0 -7
  68. package/dist/types/types/alphabetic/AllCaps.d.ts +0 -12
  69. package/dist/types/types/alphabetic/CamelCase.d.ts +0 -2
  70. package/dist/types/types/alphabetic/CapFirstAlpha.d.ts +0 -13
  71. package/dist/types/types/alphabetic/CapitalizeWords.d.ts +0 -4
  72. package/dist/types/types/alphabetic/DashToSnake.d.ts +0 -1
  73. package/dist/types/types/alphabetic/DashUppercase.d.ts +0 -14
  74. package/dist/types/types/alphabetic/Dasherize.d.ts +0 -15
  75. package/dist/types/types/alphabetic/HasUppercase.d.ts +0 -13
  76. package/dist/types/types/alphabetic/Intrinsic.d.ts +0 -4
  77. package/dist/types/types/alphabetic/IsCapitalized.d.ts +0 -15
  78. package/dist/types/types/alphabetic/KebabCase.d.ts +0 -12
  79. package/dist/types/types/alphabetic/LowerAllCaps.d.ts +0 -4
  80. package/dist/types/types/alphabetic/PascalCase.d.ts +0 -16
  81. package/dist/types/types/alphabetic/Pluralize.d.ts +0 -36
  82. package/dist/types/types/alphabetic/SnakeCase.d.ts +0 -14
  83. package/dist/types/types/alphabetic/alpha-characters.d.ts +0 -36
  84. package/dist/types/types/alphabetic/index.d.ts +0 -16
  85. package/dist/types/types/append-types.d.ts +0 -9
  86. package/dist/types/types/dictionary/Get.d.ts +0 -7
  87. package/dist/types/types/dictionary/index.d.ts +0 -1
  88. package/dist/types/types/fluent.d.ts +0 -51
  89. package/dist/types/types/index.d.ts +0 -34
  90. package/dist/types/types/kv/DictFromKv.d.ts +0 -6
  91. package/dist/types/types/kv/KeyValue.d.ts +0 -11
  92. package/dist/types/types/kv/KvFrom.d.ts +0 -13
  93. package/dist/types/types/kv/KvTuple.d.ts +0 -14
  94. package/dist/types/types/kv/index.d.ts +0 -4
  95. package/dist/types/types/lists/UniqueForProp.d.ts +0 -5
  96. package/dist/types/types/lists/index.d.ts +0 -1
  97. package/dist/types/types/maybe.d.ts +0 -8
  98. package/dist/types/types/props.d.ts +0 -100
  99. package/dist/types/types/ruleset-types.d.ts +0 -59
  100. package/dist/types/types/runtime.d.ts +0 -33
  101. package/dist/types/types/string-literals/Break.d.ts +0 -12
  102. package/dist/types/types/string-literals/Concat.d.ts +0 -8
  103. package/dist/types/types/string-literals/LeftWhitespace.d.ts +0 -9
  104. package/dist/types/types/string-literals/Replace.d.ts +0 -11
  105. package/dist/types/types/string-literals/RightWhitespace.d.ts +0 -9
  106. package/dist/types/types/string-literals/StringLength.d.ts +0 -10
  107. package/dist/types/types/string-literals/Trim.d.ts +0 -11
  108. package/dist/types/types/string-literals/TrimLeft.d.ts +0 -11
  109. package/dist/types/types/string-literals/TrimRight.d.ts +0 -11
  110. package/dist/types/types/string-literals/form-fields.d.ts +0 -12
  111. package/dist/types/types/string-literals/index.d.ts +0 -10
  112. package/dist/types/types/tuples/DictArray.d.ts +0 -19
  113. package/dist/types/types/tuples/FirstKey.d.ts +0 -8
  114. package/dist/types/types/tuples/FirstKeyValue.d.ts +0 -8
  115. package/dist/types/types/tuples/FirstOfEach.d.ts +0 -11
  116. package/dist/types/types/tuples/FromDictArray.d.ts +0 -10
  117. package/dist/types/types/tuples/SecondOfEach.d.ts +0 -10
  118. package/dist/types/types/tuples/index.d.ts +0 -6
  119. package/dist/types/types/type-conversion/TupleToUnion.d.ts +0 -10
  120. package/dist/types/types/type-conversion/UnionToIntersection.d.ts +0 -5
  121. package/dist/types/types/type-conversion/UnionToTuple.d.ts +0 -9
  122. package/dist/types/types/type-conversion/index.d.ts +0 -3
  123. package/dist/types/types/type-testing.d.ts +0 -13
  124. package/dist/types/utility/api/api.d.ts +0 -2
  125. package/dist/types/utility/api/index.d.ts +0 -1
  126. package/dist/types/utility/createFnWithProps.d.ts +0 -1
  127. package/dist/types/utility/dictionary/arrayToKeyLookup.d.ts +0 -10
  128. package/dist/types/utility/dictionary/dictFilter.d.ts +0 -8
  129. package/dist/types/utility/dictionary/dictionaryTransform.d.ts +0 -9
  130. package/dist/types/utility/dictionary/entries.d.ts +0 -17
  131. package/dist/types/utility/dictionary/index.d.ts +0 -8
  132. package/dist/types/utility/dictionary/kv/dictToKv.d.ts +0 -16
  133. package/dist/types/utility/dictionary/kv/filterDictArray.d.ts +0 -9
  134. package/dist/types/utility/dictionary/kv/index.d.ts +0 -4
  135. package/dist/types/utility/dictionary/kv/kv.d.ts +0 -10
  136. package/dist/types/utility/dictionary/kv/kvToDict.d.ts +0 -15
  137. package/dist/types/utility/dictionary/mapValues.d.ts +0 -13
  138. package/dist/types/utility/dictionary/strArrayToDict.d.ts +0 -6
  139. package/dist/types/utility/dictionary/valuesOfProp.d.ts +0 -1
  140. package/dist/types/utility/index.d.ts +0 -10
  141. package/dist/types/utility/keys.d.ts +0 -5
  142. package/dist/types/utility/literals/ExplicitFunction.d.ts +0 -6
  143. package/dist/types/utility/literals/arrayToObject.d.ts +0 -41
  144. package/dist/types/utility/literals/defineType.d.ts +0 -8
  145. package/dist/types/utility/literals/identity.d.ts +0 -6
  146. package/dist/types/utility/literals/index.d.ts +0 -5
  147. package/dist/types/utility/literals/literal.d.ts +0 -41
  148. package/dist/types/utility/map-reduce/filter.d.ts +0 -26
  149. package/dist/types/utility/map-reduce/index.d.ts +0 -1
  150. package/dist/types/utility/modelling/IoModel.d.ts +0 -26
  151. package/dist/types/utility/modelling/Model.d.ts +0 -22
  152. package/dist/types/utility/modelling/index.d.ts +0 -1
  153. package/dist/types/utility/ruleset.d.ts +0 -18
  154. package/dist/types/utility/runtime/condition.d.ts +0 -3
  155. package/dist/types/utility/runtime/conditions/index.d.ts +0 -12
  156. package/dist/types/utility/runtime/conditions/isArray.d.ts +0 -2
  157. package/dist/types/utility/runtime/conditions/isBoolean.d.ts +0 -5
  158. package/dist/types/utility/runtime/conditions/isFalse.d.ts +0 -4
  159. package/dist/types/utility/runtime/conditions/isFunction.d.ts +0 -15
  160. package/dist/types/utility/runtime/conditions/isLiteral.d.ts +0 -2
  161. package/dist/types/utility/runtime/conditions/isNull.d.ts +0 -1
  162. package/dist/types/utility/runtime/conditions/isNumber.d.ts +0 -1
  163. package/dist/types/utility/runtime/conditions/isObject.d.ts +0 -10
  164. package/dist/types/utility/runtime/conditions/isString.d.ts +0 -2
  165. package/dist/types/utility/runtime/conditions/isSymbol.d.ts +0 -1
  166. package/dist/types/utility/runtime/conditions/isTrue.d.ts +0 -20
  167. package/dist/types/utility/runtime/conditions/isUndefined.d.ts +0 -1
  168. package/dist/types/utility/runtime/ifTypeOf.d.ts +0 -23
  169. package/dist/types/utility/runtime/index.d.ts +0 -5
  170. package/dist/types/utility/runtime/type.d.ts +0 -27
  171. package/dist/types/utility/runtime/withValue.d.ts +0 -19
  172. package/dist/types/utility/state/Configurator.d.ts +0 -36
  173. package/dist/types/utility/state/FluentConfigurator.d.ts +0 -27
  174. package/dist/types/utility/state/index.d.ts +0 -3
  175. package/src/types/alphabetic/Intrinsic.ts +0 -6
  176. package/src/utility/modelling/IoModel.ts +0 -38
  177. package/tests/FluentApi-spec.ts +0 -90
  178. package/tests/FluentConfigurator-spec.hold +0 -88
  179. package/tests/IoModel-spec.hold +0 -209
@@ -1,88 +0,0 @@
1
- import { FluentConfigurator, keys } from "../src";
2
- import { mySong, Playlist, Song } from "./data/index";
3
- import { SimpleTable } from "./data/SimpleTable";
4
-
5
- describe("Configurator => ", () => {
6
- it("Call to configurator returns API", () => {
7
- const c = FluentConfigurator();
8
- expect(typeof c.done).toBe("function");
9
- expect(typeof c.done()).toBe("object");
10
- expect(Object.keys(c.done())).toHaveLength(0);
11
- });
12
-
13
- it("Configurator with empty initial state, can have props added using set() and fluent API style", () => {
14
- const c = FluentConfigurator().set("a", 5).set("b", "foobar").done();
15
- expect(c).toHaveProperty("a");
16
- expect(typeof c.a).toBe("number");
17
- expect(c).toHaveProperty("b");
18
- expect(typeof c.b).toBe("string");
19
- });
20
-
21
- it("Configurator with starting state, can have props added using fluent API style", () => {
22
- const start = { foo: "bar", bar: "baz" };
23
- const c = FluentConfigurator(start).set("b", "foobar").set("a", 5).done();
24
- console.log(keys(c));
25
-
26
-
27
- // added state
28
- expect(c).toHaveProperty("a", 5);
29
- expect(typeof c.a).toBe("number");
30
- expect(c).toHaveProperty("b", "foobar");
31
- expect(typeof c.b).toBe("string");
32
-
33
- // starting state
34
- expect(c).toHaveProperty("foo");
35
- // TODO: need to ensure initial state is available to type system
36
- // expect(typeof c.foo).toBe("string");
37
- // expect(c.foo).toBe(start.foo);
38
- expect(c).toHaveProperty("bar");
39
- // expect(typeof c.bar).toBe("string");
40
- // expect(c.bar).toBe(start.bar);
41
- });
42
-
43
- it("Configurator stores Table objects and keeps the typing", () => {
44
- const c = FluentConfigurator()
45
- .set("songs", SimpleTable(Song))
46
- .set("playlists", SimpleTable(Playlist))
47
- .done();
48
- // structure
49
- expect(c).toHaveProperty("songs");
50
- expect(c.songs).toHaveProperty("is");
51
- expect(c.songs).toHaveProperty("select");
52
- expect(c).toHaveProperty("playlists");
53
- expect(c.playlists).toHaveProperty("is");
54
- expect(c.playlists).toHaveProperty("select");
55
- // type guards
56
- // TODO: get back to working types
57
- expect((c.songs as any).is(mySong)).toBe(true);
58
- expect((c.songs as any).is({ foo: false })).toBe(false);
59
- });
60
-
61
- it("set() function is able to set a simple value and have type retained", () => {
62
- const c = FluentConfigurator()
63
- .set("songs", SimpleTable(Song))
64
- .set("playlists", SimpleTable(Playlist))
65
- .set("foo", 15)
66
- .set("bar", 1);
67
- const t = c.done();
68
- // TODO: get back to working types
69
- expect((t.songs as any).is(mySong)).toBe(true);
70
- expect((t.songs as any).is({ foo: false })).toBe(false);
71
- expect(typeof t.songs).toBe("object");
72
- expect(typeof t.playlists).toBe("object");
73
- expect(typeof t.foo).toBe("number");
74
- expect(typeof t.bar).toBe("number");
75
- });
76
-
77
- it("a partially typed configurator can be configured with set()", () => {
78
- const c = FluentConfigurator<{ songs: object; playlists: object }>()
79
- .set("songs", SimpleTable(Song))
80
- .set("playlists", SimpleTable(Playlist))
81
- .set("foobar", true)
82
- .done();
83
-
84
- expect(c.songs.name).toBe("Song");
85
- expect(c.playlists.name).toBe("Playlist");
86
- expect(c.foobar).toBe(true);
87
- });
88
- });
@@ -1,209 +0,0 @@
1
- import * as t from "io-ts";
2
- import { isLeft, isRight } from "fp-ts/Either";
3
- import {
4
- Equal,
5
- NotEqual,
6
- Expect,
7
- ExpectExtends,
8
- ExpectFalse,
9
- ExpectTrue,
10
- } from "@type-challenges/utils";
11
- import { IoModel } from "~/utility";
12
-
13
- export const mySong = {
14
- artist: "Billy Idol",
15
- song: "Whiplash Smile",
16
- };
17
-
18
- const SongMeta = t.partial({ year: t.number, genre: t.string });
19
- const req = { name: t.string, artist: t.string };
20
- const optional = { album: t.string, meta: SongMeta };
21
-
22
- const Song = IoModel("Song", req, optional);
23
- type SongType = t.TypeOf<typeof Song>;
24
- const goodSong = { name: "My Song", artist: "Elton John" };
25
- const badSong = { name: "Tom Fuckery" };
26
-
27
- const playReq = { name: t.string, owner: t.string };
28
- /** note that `Playlist` only has required props */
29
- const Playlist = IoModel("Playlist", playReq);
30
- type PlaylistType = t.TypeOf<typeof Playlist>;
31
- const goodPlaylist = { name: "a jumble of songs", owner: "Kris Kross" };
32
- const extraPlaylist = { name: "if only", owner: "fake dude", badProp: true };
33
- const badPlaylist = { name: "if only", owner: 42 };
34
-
35
- describe("Model configurator => ", () => {
36
- it("Model function returns a model which can be converted to a type with t.TypeOf", () => {
37
- // manual creation of a model
38
- const model = t.intersection([t.type(req), t.partial(optional)], "Song");
39
- type M = t.TypeOf<typeof model>;
40
- type cases = [
41
- Expect<Equal<SongType["name"], M["name"]>>,
42
- Expect<Equal<SongType["album"], M["album"]>>,
43
- Expect<Equal<SongType["artist"], M["artist"]>>
44
- ];
45
- const typeTests: cases = [true, true, true];
46
- expect(typeTests).toBe(typeTests);
47
- });
48
-
49
- it("Model's name is a literal type, not a string", () => {
50
- type cases = [
51
- Expect<NotEqual<typeof Song["name"], "string">>,
52
- Expect<Equal<typeof Song["name"], "Song">>,
53
- Expect<NotEqual<typeof Playlist["name"], "string">>,
54
- Expect<Equal<typeof Playlist["name"], "Playlist">>
55
- ];
56
- const typeTests: cases = [true, true, true, true];
57
- expect(typeTests).toBe(typeTests);
58
- });
59
-
60
- it("Model function returns a model who's type guard works as expected", () => {
61
- expect(Song.is(goodSong)).toBe(true);
62
- expect(Song.is(badSong)).toBe(false);
63
- expect(Playlist.is(goodPlaylist)).toBe(true);
64
- expect(Playlist.is(badPlaylist)).toBe(false);
65
- });
66
-
67
- it("extra model properties pass the type guard but extra prop is not part of type", () => {
68
- expect(Playlist.is(extraPlaylist)).toBe(true);
69
- if (Playlist.is(extraPlaylist)) {
70
- type E = typeof extraPlaylist;
71
- type cases = [
72
- Expect<ExpectExtends<keyof E, keyof PlaylistType>>,
73
- Expect<NotEqual<E, PlaylistType>>,
74
- Expect<Equal<keyof E, "name" | "owner" | "badProp">>,
75
- Expect<NotEqual<keyof PlaylistType, "name" | "owner" | "badProp">>,
76
- Expect<Equal<keyof PlaylistType, "name" | "owner">>
77
- ];
78
- const typeTests: cases = [true, true, true, true, true];
79
- expect(typeTests).toBe(typeTests);
80
- } else {
81
- throw new Error("extra params in object should still pass the type guard!");
82
- }
83
- });
84
-
85
- it("Model function returns a decoder which works as expected", () => {
86
- // basics
87
- expect(Song.decode(goodSong)._tag).toBe("Right");
88
- expect(Song.decode(badSong)._tag).toBe("Left");
89
- expect(Playlist.decode(goodPlaylist)._tag).toBe("Right");
90
- expect(Playlist.decode(extraPlaylist)._tag).toBe("Right");
91
- expect(Playlist.decode(badPlaylist)._tag).toBe("Left");
92
-
93
- // addressing extra properties
94
- const extra = Playlist.decode(extraPlaylist);
95
- if (isRight(extra)) {
96
- // model props represented and correct
97
- expect(extra.right.name).toBe(extraPlaylist.name);
98
- expect(extra.right.owner).toBe(extraPlaylist.owner);
99
- // extra props are still there at run time
100
- expect(Object.keys(extra.right)).toContain("badProp");
101
- // but they are not available to the type system
102
- type cases = [ExpectFalse<ExpectExtends<keyof typeof extra, "badProp">>];
103
- const typeTests: cases = [false];
104
- expect(typeTests).toBe(typeTests);
105
- } else {
106
- throw new Error("decoder asserted a playlist with extra props as being invalid!");
107
- }
108
-
109
- const invalid = Playlist.decode(badPlaylist);
110
- if (isLeft(invalid)) {
111
- type cases = [Expect<ExpectExtends<typeof invalid["left"], t.Errors>>];
112
- const typeTests: cases = [true];
113
- expect(typeTests).toBe(typeTests);
114
- } else {
115
- throw new Error("decoder asserted a invalid playlist was valid!");
116
- }
117
-
118
- const valid = Playlist.decode(goodPlaylist);
119
- if (isRight(valid)) {
120
- type cases = [Expect<ExpectExtends<typeof valid["right"], PlaylistType>>];
121
- const typeTests: cases = [true];
122
- expect(typeTests).toBe(typeTests);
123
- } else {
124
- throw new Error("decoder asserted an valid playlist was invalid!");
125
- }
126
- });
127
-
128
- it("if model is given non PascalCase name it will be converted to PascalCase", () => {
129
- const simple = IoModel("simple", { name: t.string });
130
- const camel = IoModel("camelCase", { name: t.string });
131
- const snake = IoModel("snake_case", { name: t.string });
132
- const dash = IoModel("dash-case", { name: t.string });
133
-
134
- expect(simple.name).toBe("Simple");
135
- expect(camel.name).toBe("CamelCase");
136
- expect(snake.name).toBe("SnakeCase");
137
- expect(dash.name).toBe("DashCase");
138
-
139
- type cases = [
140
- ExpectTrue<Equal<typeof simple["name"], "Simple">>,
141
- ExpectTrue<Equal<typeof camel["name"], "CamelCase">>,
142
- ExpectTrue<Equal<typeof snake["name"], "SnakeCase">>,
143
- ExpectTrue<Equal<typeof dash["name"], "DashCase">>
144
- ];
145
- const typeTests: cases = [true, true, true, true];
146
- expect(typeTests).toBe(typeTests);
147
- });
148
-
149
- it("Models put into an array can be retrieved in full fidelity", () => {
150
- const arr = [Song, Playlist];
151
-
152
- // this will resolve to a union of Song and Playlist model structures
153
- type Union = SongType | PlaylistType;
154
-
155
- for (const m of arr) {
156
- // run-time has a string for name
157
- expect(typeof m.name).toBe("string");
158
-
159
- // I naive assumption would be that this would be a distinctly typed
160
- // type structure for the underlying model but each element of the array
161
- // is -- in fact -- still just a union of SongType and PlaylistType
162
- type NaiveUnion = t.TypeOf<typeof m>;
163
-
164
- // @ts-ignore
165
- type cases = [
166
- // type system extends from "string"
167
- Expect<ExpectExtends<string, typeof m.name>>,
168
- // but is a string literal (aka, narrower than a string in definition)
169
- Expect<NotEqual<typeof m.name, string>>,
170
- // the overall data structure extends from IModel
171
- Expect<ExpectExtends<IoModel<any, any>, typeof m>>,
172
- // adding in the literal name should cause no harm
173
- Expect<ExpectExtends<IoModel<any, typeof m.name>, typeof m>>,
174
- // unfortunately, since we still don't know which of the models
175
- // we're dealing with, we can't test the fidelity of the underlying
176
- // model's TS typing
177
- Expect<Equal<NaiveUnion, Union>>
178
- ];
179
-
180
- // Because the `name` property is a literal type (versus just a string),
181
- // however, the Union types we've been dealing with are still _distinct_
182
- // for each model is not lost. This allows us to use a simple conditional
183
- // logic and get full type fidelity
184
- if (m.name === "Song") {
185
- type SpecificModel = t.TypeOf<typeof m>;
186
-
187
- // @ts-ignore
188
- type cases = [
189
- // the specific model will extend the union
190
- Expect<ExpectExtends<Union, SpecificModel>>,
191
- // but is no longer equal as it's type has been narrowed by inference
192
- Expect<NotEqual<SpecificModel, Union>>
193
- ];
194
- }
195
-
196
- if (m.name === "Playlist") {
197
- type SpecificModel = t.TypeOf<typeof m>;
198
-
199
- // @ts-ignore
200
- type cases = [
201
- // the specific model will extend the union
202
- Expect<ExpectExtends<Union, SpecificModel>>,
203
- // but is no longer equal as it's type has been narrowed by inference
204
- Expect<NotEqual<SpecificModel, Union>>
205
- ];
206
- }
207
- }
208
- });
209
- });