inferred-types 0.37.0 → 0.37.1

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 (280) hide show
  1. package/dist/index.d.ts +2745 -0
  2. package/dist/index.js +854 -0
  3. package/package.json +6 -12
  4. package/.eslintrc +0 -77
  5. package/.github/workflows/main.yml +0 -34
  6. package/.github/workflows/other.yml +0 -15
  7. package/.nvmrc +0 -1
  8. package/.prettierrc.js +0 -3
  9. package/.vscode/launch.json +0 -27
  10. package/.vscode/settings.json +0 -19
  11. package/devops/build.js +0 -243
  12. package/docs/builder-overview.md +0 -45
  13. package/docs/builder.md +0 -94
  14. package/src/errors/ReadOnlyViolation.ts +0 -3
  15. package/src/errors/index.ts +0 -12
  16. package/src/index.ts +0 -14
  17. package/src/runtime/README.md +0 -3
  18. package/src/runtime/api/api.ts +0 -10
  19. package/src/runtime/api/index.ts +0 -12
  20. package/src/runtime/builders/Model.ts +0 -25
  21. package/src/runtime/builders/url.ts +0 -15
  22. package/src/runtime/combinators/and.ts +0 -15
  23. package/src/runtime/combinators/filter.ts +0 -267
  24. package/src/runtime/combinators/index.ts +0 -4
  25. package/src/runtime/combinators/not.ts +0 -15
  26. package/src/runtime/combinators/or.ts +0 -5
  27. package/src/runtime/createFnWithProps.ts +0 -37
  28. package/src/runtime/dictionary/arrayToKeyLookup.ts +0 -19
  29. package/src/runtime/dictionary/defineProperties.ts +0 -35
  30. package/src/runtime/dictionary/dictArr.ts +0 -69
  31. package/src/runtime/dictionary/dictionaryTransform.ts +0 -22
  32. package/src/runtime/dictionary/entries.ts +0 -33
  33. package/src/runtime/dictionary/index.ts +0 -21
  34. package/src/runtime/dictionary/kv/dictToKv.ts +0 -21
  35. package/src/runtime/dictionary/kv/filterDictArray.ts +0 -31
  36. package/src/runtime/dictionary/kv/index.ts +0 -15
  37. package/src/runtime/dictionary/kv/kv.ts +0 -18
  38. package/src/runtime/dictionary/kv/kvToDict.ts +0 -24
  39. package/src/runtime/dictionary/mapTo.ts +0 -206
  40. package/src/runtime/dictionary/mapValues.ts +0 -23
  41. package/src/runtime/dictionary/merge.ts +0 -36
  42. package/src/runtime/dictionary/strArrayToDict.ts +0 -12
  43. package/src/runtime/index.ts +0 -23
  44. package/src/runtime/keys.ts +0 -16
  45. package/src/runtime/lists/asArray.ts +0 -38
  46. package/src/runtime/lists/createConverter.ts +0 -62
  47. package/src/runtime/lists/groupBy.ts +0 -15
  48. package/src/runtime/lists/index.ts +0 -15
  49. package/src/runtime/literals/ExplicitFunction.ts +0 -10
  50. package/src/runtime/literals/Suggest.ts +0 -19
  51. package/src/runtime/literals/arrayToObject.ts +0 -78
  52. package/src/runtime/literals/box.ts +0 -98
  53. package/src/runtime/literals/defineType.ts +0 -20
  54. package/src/runtime/literals/ensureLeading.ts +0 -17
  55. package/src/runtime/literals/ensureTrailing.ts +0 -17
  56. package/src/runtime/literals/identity.ts +0 -12
  57. package/src/runtime/literals/index.ts +0 -23
  58. package/src/runtime/literals/literal.ts +0 -48
  59. package/src/runtime/literals/pathJoin.ts +0 -33
  60. package/src/runtime/literals/stripLeading.ts +0 -15
  61. package/src/runtime/literals/stripTrailing.ts +0 -15
  62. package/src/runtime/literals/wide.ts +0 -13
  63. package/src/runtime/ruleset.ts +0 -42
  64. package/src/runtime/runtime/README.md +0 -3
  65. package/src/runtime/runtime/condition.ts +0 -13
  66. package/src/runtime/runtime/index.ts +0 -16
  67. package/src/runtime/runtime/type.ts +0 -127
  68. package/src/runtime/runtime/withValue.ts +0 -39
  69. package/src/runtime/state/Configurator.ts +0 -76
  70. package/src/runtime/state/FluentConfigurator.ts +0 -49
  71. package/src/runtime/state/index.ts +0 -13
  72. package/src/runtime/type-checks/ifSameType.ts +0 -20
  73. package/src/runtime/type-checks/ifTypeOf.ts +0 -124
  74. package/src/runtime/type-checks/index.ts +0 -24
  75. package/src/runtime/type-checks/isArray.ts +0 -34
  76. package/src/runtime/type-checks/isBoolean.ts +0 -24
  77. package/src/runtime/type-checks/isFalse.ts +0 -29
  78. package/src/runtime/type-checks/isFunction.ts +0 -26
  79. package/src/runtime/type-checks/isNull.ts +0 -26
  80. package/src/runtime/type-checks/isNumber.ts +0 -20
  81. package/src/runtime/type-checks/isObject.ts +0 -22
  82. package/src/runtime/type-checks/isString.ts +0 -34
  83. package/src/runtime/type-checks/isSymbol.ts +0 -3
  84. package/src/runtime/type-checks/isTrue.ts +0 -31
  85. package/src/runtime/type-checks/isUndefined.ts +0 -33
  86. package/src/runtime/type-checks/startsWith.ts +0 -107
  87. package/src/runtime/valueTypes.ts +0 -48
  88. package/src/types/Api.ts +0 -16
  89. package/src/types/Constructor.ts +0 -5
  90. package/src/types/EnumValues.ts +0 -14
  91. package/src/types/ExpandRecursively.ts +0 -12
  92. package/src/types/FunctionType.ts +0 -19
  93. package/src/types/If.ts +0 -10
  94. package/src/types/Include.ts +0 -18
  95. package/src/types/KeyedRecord.ts +0 -21
  96. package/src/types/Keys.ts +0 -26
  97. package/src/types/Length.ts +0 -8
  98. package/src/types/Mutable.ts +0 -8
  99. package/src/types/Narrowable.ts +0 -5
  100. package/src/types/Not.ts +0 -13
  101. package/src/types/Numeric.ts +0 -20
  102. package/src/types/Opaque.ts +0 -11
  103. package/src/types/README.md +0 -3
  104. package/src/types/Retain.ts +0 -16
  105. package/src/types/SimplifyObject.ts +0 -12
  106. package/src/types/Transformer.ts +0 -15
  107. package/src/types/TypeGuard.ts +0 -7
  108. package/src/types/Where.ts +0 -40
  109. package/src/types/alphabetic/AllCaps.ts +0 -15
  110. package/src/types/alphabetic/CamelCase.ts +0 -3
  111. package/src/types/alphabetic/CapFirstAlpha.ts +0 -23
  112. package/src/types/alphabetic/CapitalizeWords.ts +0 -9
  113. package/src/types/alphabetic/Cardinality.ts +0 -80
  114. package/src/types/alphabetic/DashToSnake.ts +0 -3
  115. package/src/types/alphabetic/DashUppercase.ts +0 -19
  116. package/src/types/alphabetic/Dasherize.ts +0 -23
  117. package/src/types/alphabetic/EnsureLeading.ts +0 -24
  118. package/src/types/alphabetic/EnsureTrailing.ts +0 -24
  119. package/src/types/alphabetic/HasUppercase.ts +0 -16
  120. package/src/types/alphabetic/IsCapitalized.ts +0 -18
  121. package/src/types/alphabetic/KebabCase.ts +0 -13
  122. package/src/types/alphabetic/LowerAllCaps.ts +0 -5
  123. package/src/types/alphabetic/PascalCase.ts +0 -29
  124. package/src/types/alphabetic/PathJoin.ts +0 -54
  125. package/src/types/alphabetic/Pluralize.ts +0 -112
  126. package/src/types/alphabetic/SnakeCase.ts +0 -27
  127. package/src/types/alphabetic/StripLeading.ts +0 -23
  128. package/src/types/alphabetic/StripTrailing.ts +0 -23
  129. package/src/types/alphabetic/Url.ts +0 -29
  130. package/src/types/alphabetic/alpha-characters.ts +0 -81
  131. package/src/types/alphabetic/index.ts +0 -32
  132. package/src/types/append-types.ts +0 -10
  133. package/src/types/boolean-logic/EndsWith.ts +0 -40
  134. package/src/types/boolean-logic/Extends.ts +0 -22
  135. package/src/types/boolean-logic/HasParameters.ts +0 -21
  136. package/src/types/boolean-logic/Includes.ts +0 -33
  137. package/src/types/boolean-logic/IsLiteral.ts +0 -101
  138. package/src/types/boolean-logic/IsScalar.ts +0 -20
  139. package/src/types/boolean-logic/IsUndefined.ts +0 -20
  140. package/src/types/boolean-logic/Or.ts +0 -12
  141. package/src/types/boolean-logic/StartsWith.ts +0 -42
  142. package/src/types/boolean-logic/TypeDefault.ts +0 -58
  143. package/src/types/boolean-logic/array.ts +0 -57
  144. package/src/types/boolean-logic/boolean.ts +0 -84
  145. package/src/types/boolean-logic/equivalency.ts +0 -15
  146. package/src/types/boolean-logic/index.ts +0 -14
  147. package/src/types/boolean-logic/object.ts +0 -30
  148. package/src/types/boolean-logic/string.ts +0 -21
  149. package/src/types/dictionary/DictChangeValue.ts +0 -34
  150. package/src/types/dictionary/DictPartialApplication.ts +0 -30
  151. package/src/types/dictionary/DictPrependWithFn.ts +0 -23
  152. package/src/types/dictionary/DictReturnValues.ts +0 -27
  153. package/src/types/dictionary/Get.ts +0 -14
  154. package/src/types/dictionary/MapTo.ts +0 -428
  155. package/src/types/dictionary/MutableProps.ts +0 -19
  156. package/src/types/dictionary/RequireProps.ts +0 -15
  157. package/src/types/dictionary/SameKeys.ts +0 -11
  158. package/src/types/dictionary/index.ts +0 -21
  159. package/src/types/dictionary/props.ts +0 -145
  160. package/src/types/fluent/fluent.ts +0 -61
  161. package/src/types/fluent/index.ts +0 -12
  162. package/src/types/functions/FinalReturn.ts +0 -12
  163. package/src/types/functions/LogicFunction.ts +0 -4
  164. package/src/types/functions/index.ts +0 -13
  165. package/src/types/index.ts +0 -49
  166. package/src/types/kv/DictFromKv.ts +0 -3
  167. package/src/types/kv/KeyValue.ts +0 -12
  168. package/src/types/kv/KvFrom.ts +0 -8
  169. package/src/types/kv/KvTuple.ts +0 -14
  170. package/src/types/kv/index.ts +0 -15
  171. package/src/types/lists/AfterFirst.ts +0 -10
  172. package/src/types/lists/ConvertAndMap.ts +0 -152
  173. package/src/types/lists/FilterTuple.ts +0 -20
  174. package/src/types/lists/First.ts +0 -8
  175. package/src/types/lists/FirstString.ts +0 -4
  176. package/src/types/lists/Split.ts +0 -21
  177. package/src/types/lists/UniqueForProp.ts +0 -18
  178. package/src/types/lists/index.ts +0 -18
  179. package/src/types/literal-unions/OptRequired.ts +0 -4
  180. package/src/types/literal-unions/index.ts +0 -1
  181. package/src/types/maybe.ts +0 -9
  182. package/src/types/ruleset-types.ts +0 -76
  183. package/src/types/runtime.ts +0 -39
  184. package/src/types/string-literals/Break.ts +0 -22
  185. package/src/types/string-literals/Concat.ts +0 -9
  186. package/src/types/string-literals/LeftWhitespace.ts +0 -13
  187. package/src/types/string-literals/Replace.ts +0 -17
  188. package/src/types/string-literals/RightWhitespace.ts +0 -13
  189. package/src/types/string-literals/StringLength.ts +0 -34
  190. package/src/types/string-literals/Trim.ts +0 -15
  191. package/src/types/string-literals/TrimLeft.ts +0 -14
  192. package/src/types/string-literals/TrimRight.ts +0 -14
  193. package/src/types/string-literals/form-fields.ts +0 -15
  194. package/src/types/string-literals/index.ts +0 -21
  195. package/src/types/tuples/DictArray.ts +0 -21
  196. package/src/types/tuples/FirstKey.ts +0 -10
  197. package/src/types/tuples/FirstKeyValue.ts +0 -9
  198. package/src/types/tuples/FirstOfEach.ts +0 -13
  199. package/src/types/tuples/FromDictArray.ts +0 -14
  200. package/src/types/tuples/SecondOfEach.ts +0 -13
  201. package/src/types/tuples/index.ts +0 -17
  202. package/src/types/type-conversion/TupleToUnion.ts +0 -9
  203. package/src/types/type-conversion/UnionToIntersection.ts +0 -9
  204. package/src/types/type-conversion/UnionToTuple.ts +0 -20
  205. package/src/types/type-conversion/Widen.ts +0 -22
  206. package/src/types/type-conversion/index.ts +0 -16
  207. package/src/types/type-testing.ts +0 -14
  208. package/tests/CamelCase-spec.ts +0 -20
  209. package/tests/Configurator-spec.hold +0 -106
  210. package/tests/ExplicitFunction-spec.ts +0 -50
  211. package/tests/IncludeAndRetain-spec.ts +0 -67
  212. package/tests/Includes-spec.ts +0 -36
  213. package/tests/KebabCase-spec.ts +0 -21
  214. package/tests/PascalCase-spec.ts +0 -22
  215. package/tests/Pluralize-spec.ts +0 -23
  216. package/tests/SnakeCase-spec.ts +0 -21
  217. package/tests/Where.spec.ts +0 -38
  218. package/tests/arrayToKeyLookup-spec.ts +0 -17
  219. package/tests/arrayToObject-spec.ts +0 -115
  220. package/tests/boolean-logic/Contains.test.ts +0 -55
  221. package/tests/boolean-logic/HasParameters.ts +0 -29
  222. package/tests/boolean-logic/IsLiteral.spec.ts +0 -65
  223. package/tests/boolean-logic/boolean.spec.ts +0 -21
  224. package/tests/boolean-logic/filter.spec.ts +0 -52
  225. package/tests/constructor.spec.ts +0 -42
  226. package/tests/createFnWithProps.spec.ts +0 -14
  227. package/tests/data/SimpleTable.hold +0 -21
  228. package/tests/data/index.ts +0 -12
  229. package/tests/data/playlist.hold +0 -25
  230. package/tests/data/song.hold +0 -23
  231. package/tests/defineType-spec.ts +0 -57
  232. package/tests/dictionary/DictChangeValue.test.ts +0 -30
  233. package/tests/dictionary/DictPartialApplication.test.ts +0 -43
  234. package/tests/dictionary/DictReturnValues.test.ts +0 -36
  235. package/tests/dictionary/Get.spec.ts +0 -28
  236. package/tests/dictionary/IntersectingKeys.test.ts +0 -42
  237. package/tests/dictionary/MutableProps.test.ts +0 -30
  238. package/tests/dictionary/OptionalKeys.test.ts +0 -24
  239. package/tests/dictionary/PrependValuesWithFunction.test.ts +0 -34
  240. package/tests/dictionary/RequireProps.test.ts +0 -21
  241. package/tests/dictionary/RequiredKeys.test.ts +0 -53
  242. package/tests/dictionary/TypeDefault.test.ts +0 -76
  243. package/tests/dictionary/mapTo.test.ts +0 -388
  244. package/tests/dictionary/merge.test.ts +0 -41
  245. package/tests/dictionaryTransform-spec.ts +0 -280
  246. package/tests/ifTypeOf-spec.ts +0 -191
  247. package/tests/kv/KeyValue-spec.ts +0 -22
  248. package/tests/kv/SameKeys-spec.ts +0 -35
  249. package/tests/kv/dict-to-kv-and-back.spec.ts +0 -169
  250. package/tests/kv/entries-spec.ts +0 -65
  251. package/tests/kv/keys.spec.ts +0 -66
  252. package/tests/kv/kv-spec.ts +0 -20
  253. package/tests/lists/First.test.ts +0 -43
  254. package/tests/lists/Length.test.ts +0 -19
  255. package/tests/lists/Split.test.ts +0 -29
  256. package/tests/lists/UniqueForProp.spec.ts +0 -59
  257. package/tests/lists/asArray.test.ts +0 -109
  258. package/tests/lists/dictArr.test.ts +0 -110
  259. package/tests/literal-spec.ts +0 -82
  260. package/tests/literals/AllCaps.spec.ts +0 -33
  261. package/tests/literals/CamelCase.spec.ts +0 -109
  262. package/tests/literals/Dasherize.spec.ts +0 -107
  263. package/tests/literals/EnsureStripLeadingTrailing.test.ts +0 -79
  264. package/tests/literals/HasUppercase.spec.ts +0 -33
  265. package/tests/literals/PascalCase.spec.ts +0 -109
  266. package/tests/literals/PathJoin.test.ts +0 -111
  267. package/tests/literals/SnakeCase.spec.ts +0 -109
  268. package/tests/literals/box.test.ts +0 -85
  269. package/tests/literals/whitespace-capture.spec.ts +0 -60
  270. package/tests/mapValues-spec.ts +0 -50
  271. package/tests/props-spec.ts +0 -234
  272. package/tests/runtime/condition.spec.ts +0 -19
  273. package/tests/runtime/if-is.spec.ts +0 -390
  274. package/tests/runtime/map-and-convert.test.ts +0 -31
  275. package/tests/runtime/type.spec.ts +0 -190
  276. package/tests/strArrayToDict-spec.ts +0 -40
  277. package/tests/tuples/TupleToUnion.spec.ts +0 -20
  278. package/tests/withValue.spec.ts +0 -173
  279. package/tsconfig.json +0 -36
  280. package/vitest.config.ts +0 -17
@@ -1,65 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
-
3
- import type { Expect, NotEqual, Equal, ExpectExtends } from "@type-challenges/utils";
4
- import { entries } from "src/runtime";
5
-
6
- describe("entries() => ", () => {
7
- it("literal types are retained", () => {
8
- const obj = { foo: 1, bar: "hi" } as const;
9
- type Value = 1 | "hi";
10
-
11
- for (const [k, v] of entries(obj)) {
12
- type cases = [
13
- // the key should extend string
14
- Expect<ExpectExtends<string, typeof k>>,
15
- // but because it's a literal, it should not be a string
16
- Expect<NotEqual<string, typeof k>>,
17
- // this is shown as a union of literals here
18
- Expect<Equal<"foo" | "bar", typeof k>>,
19
- // the value should also be a union of the possible literals
20
- Expect<ExpectExtends<typeof v, Value>>
21
- ];
22
- const cases: cases = [true, true, true, true];
23
- expect(cases).toBe(cases);
24
-
25
- if (k === "foo") {
26
- type cases2 = [
27
- // inside a conditional, typescript knows as an
28
- // explicit type and no longer a union of keys
29
- Expect<Equal<typeof k, "foo">>,
30
- // but the value is still a union of all KV
31
- // values which makes it far less valuable
32
- Expect<Equal<typeof v, Value>>
33
- ];
34
- const c: cases2 = [true, true];
35
- expect(c).toBe(c);
36
- }
37
- }
38
-
39
- // for (const entry of entries(obj)) {
40
- // if (entry[0] === "foo") {
41
- // type K = typeof entry[0];
42
- // type V = typeof entry[1];
43
-
44
- // type cases3 = [
45
- // // inside a conditional, typescript knows as an
46
- // // explicit type and no longer a union of keys
47
- // Expect<Equal<typeof entry[0], "foo">>,
48
- // // but the value is still a union of all KV
49
- // // values which makes it far less valuable
50
- // Expect<Equal<typeof v, Value>>,
51
- // ];
52
- // const c: cases3 = [true, true];
53
- // expect(c).toBe(c);
54
- // }
55
- // }
56
- });
57
-
58
- it("values maintain their implicit type even when nested objects", () => {
59
- const obj = { foo: { bar: { baz: 42 } } };
60
- for (const [k, v] of entries(obj)) {
61
- expect(k).toBe("foo");
62
- expect(v).toBe(obj.foo);
63
- }
64
- });
65
- });
@@ -1,66 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
-
3
- import { Keys } from "src/types/Keys";
4
- import type { Expect, Equal } from "@type-challenges/utils";
5
- import { defineType, keys } from "src/runtime";
6
-
7
- describe("Keys<T>", () => {
8
- it("Keys<T> is shorthand for keyof T", () => {
9
- const obj = { foo: 1, bar: 3 };
10
- type O = keyof typeof obj;
11
- type keys = Keys<typeof obj>;
12
-
13
- type cases = [Expect<Equal<O, keys>>];
14
- const cases: cases = [true];
15
- expect(cases).toBe(cases);
16
- });
17
-
18
- it("Keys<T> can also convert an array of strings into a union type", () => {
19
- const arr = ["foo", "bar"] as const;
20
- type Arr = typeof arr;
21
- type MyKeys = Keys<Arr>;
22
-
23
- type cases = [Expect<Equal<MyKeys, "foo" | "bar">>];
24
- const cases: cases = [true];
25
- expect(cases).toBe(cases);
26
- });
27
-
28
- it("Keys<T,W> can exclude certain keys", () => {
29
- const obj = { foo: 1, bar: 3 };
30
- const arr = ["foo", "bar"] as const;
31
- type OKeys = Keys<typeof obj, "foo">;
32
- type OArr = Keys<typeof arr, "foo">;
33
-
34
- type cases = [Expect<Equal<OKeys, "bar">>, Expect<Equal<OArr, "bar">>];
35
- const cases: cases = [true, true];
36
- expect(cases).toBe(cases);
37
- });
38
- });
39
-
40
- describe("keys() utility", () => {
41
- it("with just object passed in, keys are extracted as expected", () => {
42
- const obj = defineType({ id: "123" })({ color: "red", isFavorite: false });
43
- const k = keys(obj);
44
-
45
- expect(k).toHaveLength(3);
46
- expect(k).toContain("id");
47
- expect(k).toContain("color");
48
- expect(k).toContain("isFavorite");
49
-
50
- type cases = [Expect<Equal<typeof k, ("color" | "id" | "isFavorite")[]>>];
51
- const cases: cases = [true];
52
- expect(cases).toBe(cases);
53
- });
54
-
55
- it("with object and exclusion keys, type and run-time are correct", () => {
56
- const obj = defineType({ id: "123" })({ color: "red", isFavorite: false });
57
- const k = keys(obj, "color", "id");
58
-
59
- expect(k).toHaveLength(1);
60
- expect(k).toContain("isFavorite");
61
-
62
- type cases = [Expect<Equal<typeof k, "isFavorite"[]>>];
63
- const cases: cases = [true];
64
- expect(cases).toBe(cases);
65
- });
66
- });
@@ -1,20 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
-
3
- import { keys, kv } from "src/runtime";
4
-
5
- describe("kv utils", () => {
6
- it("simple assignment works with strong literal support", () => {
7
- const t1 = kv("foo", { a: 1, b: 2, c: "hi" });
8
- const t2 = kv("bar", true);
9
-
10
- expect(typeof t1).toBe("object");
11
- expect(typeof t2).toBe("object");
12
-
13
- expect(keys(t1)).toContain("foo");
14
- expect(t1.foo.a).toBe(1);
15
- expect(t1.foo.c).toBe("hi");
16
-
17
- expect(keys(t2)).toContain("bar");
18
- expect(t2.bar).toBe(true);
19
- });
20
- });
@@ -1,43 +0,0 @@
1
- import { describe, it } from "vitest";
2
- import type { Expect, Equal } from "@type-challenges/utils";
3
- import { AfterFirst, First } from "src/types/lists";
4
-
5
- describe("First<T>, AfterFirst<T>", () => {
6
- it("First<T> with literals", () => {
7
- const arr = ["one", "two", 42] as const;
8
- type F = First<typeof arr>;
9
- type cases = [Expect<Equal<F, "one">>];
10
- const cases: cases = [true];
11
- });
12
- it("First<T> with wide types but literal array", () => {
13
- const arr = ["one" as string, "two", 42] as const;
14
- type F = First<typeof arr>;
15
- type cases = [Expect<Equal<F, string>>];
16
- const cases: cases = [true];
17
- });
18
- it("First<T> with a non const array", () => {
19
- const arr = ["one", "two", 42];
20
- type F = First<typeof arr>;
21
- type cases = [Expect<Equal<F, string | number>>];
22
- const cases: cases = [true];
23
- });
24
-
25
- it("AfterFirst<T> with literals", () => {
26
- const arr = ["one", "two", 42] as const;
27
- type AF = AfterFirst<typeof arr>;
28
- type cases = [Expect<Equal<AF, ["two", 42]>>];
29
- const cases: cases = [true];
30
- });
31
- it("AfterFirst<T> with wide types but literal array", () => {
32
- const arr = ["one", "two" as string, 42] as const;
33
- type AF = AfterFirst<typeof arr>;
34
- type cases = [Expect<Equal<AF, [string, 42]>>];
35
- const cases: cases = [true];
36
- });
37
- it("AfterFirst<T> with a non const array", () => {
38
- const arr = ["one", "two", 42];
39
- type AF = AfterFirst<typeof arr>;
40
- type cases = [Expect<Equal<AF, (string | number)[]>>];
41
- const cases: cases = [true];
42
- });
43
- });
@@ -1,19 +0,0 @@
1
- import { Equal, Expect } from "@type-challenges/utils";
2
- import { Length } from "src/types";
3
- import { describe, it } from "vitest";
4
-
5
- describe("Length<T>", () => {
6
- it("happy-path", () => {
7
- const a1 = [1, 2, 3] as const;
8
- const a2 = [1, 2, 3, 4, 5, 6] as const;
9
- type A1 = typeof a1;
10
- type A2 = typeof a2;
11
-
12
- type cases = [
13
- //
14
- Expect<Equal<Length<A1>, 3>>,
15
- Expect<Equal<Length<A2>, 6>>
16
- ];
17
- const cases: cases = [true, true];
18
- });
19
- });
@@ -1,29 +0,0 @@
1
- import { describe, it } from "vitest";
2
- import type { Expect, Equal } from "@type-challenges/utils";
3
- import { Split } from "src/types/lists";
4
-
5
- describe("Split<T, SEP>", () => {
6
- it("Split<T, SEP> with string literals", () => {
7
- const str = "hello world, nice to meet you" as const;
8
- type S = Split<typeof str, " ">;
9
-
10
- type cases = [Expect<Equal<S, ["hello", "world,", "nice", "to", "meet", "you"]>>];
11
- const cases: cases = [true];
12
- });
13
-
14
- it("Split<T, SEP> where string and separator are same", () => {
15
- const str = "hello world, 42 nice to meet you" as const;
16
- type S = Split<typeof str, typeof str>;
17
-
18
- type cases = [Expect<Equal<S, []>>];
19
- const cases: cases = [true];
20
- });
21
-
22
- it("Split<T, SEP> string is wide type", () => {
23
- const str = "hello world, 42 nice to meet you" as string;
24
- type S = Split<typeof str, ",">;
25
-
26
- type cases = [Expect<Equal<S, string[]>>];
27
- const cases: cases = [true];
28
- });
29
- });
@@ -1,59 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { Expect, Equal } from "@type-challenges/utils";
3
- import { UniqueForProp } from "src/types/lists";
4
-
5
- const narrow_data = [
6
- { id: 123, color: "blue" },
7
- { id: 456, color: "red" },
8
- ] as const;
9
- type NarrowData = typeof narrow_data;
10
-
11
- type R = { id: number; color: string };
12
- const wide_data: readonly R[] = [
13
- { id: 123, color: "blue" },
14
- { id: 456, color: "red" },
15
- ];
16
- type WideData = typeof wide_data;
17
-
18
- type R2<T extends string> = Readonly<{ id: number; color: T }>;
19
- const hybrid = <H extends R2<any>>(...data: H[]): readonly H[] => data;
20
- const hybrid_data = hybrid(
21
- ...[
22
- { id: 123, color: "blue" },
23
- { id: 456, color: "red" },
24
- ]
25
- );
26
- type HybridData = typeof hybrid_data;
27
-
28
- describe("UniqueForProp<T, P>", () => {
29
- it("narrow data works as expected", () => {
30
- type U = UniqueForProp<NarrowData, "id">;
31
-
32
- type cases = [
33
- // the expected keys are part of the union
34
- Expect<Equal<U, 123 | 456>>
35
- ];
36
-
37
- const c: cases = [true];
38
- expect(c).toBe(c);
39
- });
40
-
41
- it("wide data only knows the wide type", () => {
42
- type U = UniqueForProp<WideData, "id">;
43
-
44
- type cases = [
45
- // the keys are rolled up the wide type
46
- Expect<Equal<U, number>>
47
- ];
48
-
49
- const c: cases = [true];
50
- expect(c).toBe(c);
51
- });
52
-
53
- it("wide data only knows the wide type", () => {
54
- type U = UniqueForProp<HybridData, "id">;
55
- type cases = [Expect<Equal<U, number>>];
56
- const c: cases = [true];
57
- expect(c).toBe(c);
58
- });
59
- });
@@ -1,109 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { AsArray, asArray } from "src/runtime";
3
- import { Equal, Expect } from "@type-challenges/utils";
4
-
5
- describe("AsArray<T>", () => {
6
- it("happy path", () => {
7
- type T1 = AsArray<4>;
8
- type T2 = AsArray<4, true>;
9
- type T3 = AsArray<[4, 5, 6]>;
10
- type T4 = AsArray<[4, 5, 6], true>;
11
-
12
- type cases = [
13
- //
14
- Expect<Equal<T1, 4[]>>,
15
- Expect<Equal<T2, number[]>>,
16
- Expect<Equal<T3, [4, 5, 6]>>,
17
- Expect<Equal<T4, number[]>>
18
- ];
19
- const cases: cases = [true, true, true, true];
20
- });
21
- });
22
-
23
- describe("asArray() function", () => {
24
- it("non-array is returned as an array", () => {
25
- const i = "a";
26
- const o = asArray(i);
27
- type O = typeof o;
28
-
29
- // run-time
30
- expect(o).toEqual(["a"]);
31
- // design-time
32
- type cases = [Expect<Equal<O, string[]>>];
33
- const cases: cases = [true];
34
- });
35
-
36
- it("array is returned as an array", () => {
37
- const i = ["a"];
38
- const o = asArray(i);
39
- type O = typeof o;
40
-
41
- // run-time
42
- expect(o).toEqual(["a"]);
43
- // design-time
44
- type cases = [Expect<Equal<O, string[]>>];
45
- const cases: cases = [true];
46
- });
47
-
48
- it("non-array literal is returned as an array", () => {
49
- const i = "a" as const;
50
- const o = asArray(i, false);
51
- const o2 = asArray(i, true);
52
-
53
- type O = typeof o;
54
- type O2 = typeof o2;
55
-
56
- // run-time
57
- expect(o).toEqual(["a"]);
58
- // design-time
59
- type cases = [
60
- Expect<Equal<O, "a"[]>>, //
61
- Expect<Equal<O2, string[]>>
62
- ];
63
- const cases: cases = [true, true];
64
- });
65
-
66
- it("handling non-array element which presents as undefined", () => {
67
- type T = string | undefined;
68
- const i = undefined;
69
- const i2: T = undefined;
70
- const o = asArray(i);
71
- const o2 = asArray(i2 as T);
72
- const o3 = asArray(i2 as T, false);
73
- type O = typeof o;
74
- type O2 = typeof o2;
75
- type O3 = typeof o3;
76
-
77
- // run-time
78
- expect(o).toEqual([]);
79
- expect(o2).toEqual([]);
80
- // design-time
81
- type cases = [
82
- Expect<Equal<O, unknown[]>>, //
83
- // TODO: would be nice to extract the unknown[] part of the union
84
- Expect<Equal<O2, unknown[] | string[]>>,
85
- Expect<Equal<O3, unknown[] | string[]>>
86
- ];
87
- const cases: cases = [true, true, true];
88
- });
89
-
90
- it("handling array element which contains undefined is unaffected", () => {
91
- type T = string | undefined;
92
- const i = [undefined, "foobar"];
93
- const i2: T[] = [undefined, "foobar"];
94
- const o = asArray(i);
95
- const o2 = asArray(i2 as T[]);
96
- type O = typeof o;
97
- type O2 = typeof o2;
98
-
99
- // run-time
100
- expect(o).toEqual([undefined, "foobar"]);
101
- expect(o2).toEqual([undefined, "foobar"]);
102
- // design-time
103
- type cases = [
104
- Expect<Equal<O, (string | undefined)[]>>, //
105
- Expect<Equal<O2, T[]>>
106
- ];
107
- const cases: cases = [true, true];
108
- });
109
- });
@@ -1,110 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import type { Expect, Equal } from "@type-challenges/utils";
3
- import { dictArr, keys, literal } from "src/runtime";
4
-
5
- type O = {
6
- id: number;
7
- name: string;
8
- title: string;
9
- cost?: number;
10
- color?: string;
11
- };
12
-
13
- const genericArr: O[] = [
14
- { id: 1, name: "foo", title: "one", cost: 15 },
15
- { id: 2, name: "bar", title: "one" },
16
- { id: 3, name: "baz", title: "two", cost: 45, color: "green" },
17
- ];
18
-
19
- const literalArr = [
20
- literal({ id: 1, name: "foo", title: "one", cost: 15 }),
21
- literal({ id: 2, name: "bar", title: "one" }),
22
- literal({ id: 3, name: "baz", title: "two", cost: 45, color: "green" }),
23
- ];
24
-
25
- const wideArr = [
26
- { id: 1, name: "foo", title: "one", cost: 15 },
27
- { id: 2, name: "bar", title: "one" },
28
- { id: 3, name: "baz", title: "two", cost: 45, color: "green" },
29
- ];
30
-
31
- describe("dictArr() utility API", () => {
32
- it("returns an API when passed the array", () => {
33
- const r = dictArr(...genericArr);
34
- type R = typeof r;
35
- // runtime checks
36
- expect(typeof r.toLookup).contains("function");
37
- expect(typeof r.unique).contains("function");
38
- expect(typeof r.count).contains("function");
39
- expect(typeof r.sum).contains("function");
40
- expect(typeof r.length).contains("number");
41
-
42
- // type checks
43
- type ToLookupParam = Parameters<R["toLookup"]>[0];
44
- type UniqueParam = Parameters<R["unique"]>[0];
45
- type CountParam = Parameters<R["count"]>[0];
46
- type SumParam = Parameters<R["sum"]>[0];
47
-
48
- // type ToLookupReturn = ReturnType<R["toLookup"]>;
49
-
50
- type cases = [
51
- Expect<Equal<ToLookupParam, "name" | "title">>,
52
- Expect<Equal<UniqueParam, "id" | "name" | "title" | "cost" | "color">>,
53
- Expect<Equal<CountParam, "cost" | "color">>,
54
- Expect<Equal<SumParam, "id" | "cost">>
55
- ];
56
- const cases: cases = [true, true, true, true];
57
- });
58
-
59
- it("toLookup() creates type-strong lookup", () => {
60
- const g = dictArr(...genericArr);
61
- const l = dictArr(...literalArr);
62
- const pl = dictArr(...wideArr);
63
- const byNameG = g.toLookup("name");
64
- const byNameL = l.toLookup("name");
65
- const byNamePL = pl.toLookup("name");
66
- const kg = keys(byNameG);
67
- const kl = keys(byNameL);
68
- const kpl = keys(byNamePL);
69
- expect(kg).contains("foo");
70
- expect(kg).contains("bar");
71
- expect(kg).contains("baz");
72
-
73
- expect(kl).contains("foo");
74
- expect(kl).contains("bar");
75
- expect(kl).contains("baz");
76
-
77
- expect(kpl).contains("foo");
78
- expect(kpl).contains("bar");
79
- expect(kpl).contains("baz");
80
-
81
- const fooG = genericArr.find((i) => i.name === "foo");
82
- expect(byNameG.foo).toEqual(fooG);
83
-
84
- const fooL = literalArr.find((i) => i.name === "foo");
85
- expect(byNameL.foo).toEqual(fooL);
86
- });
87
-
88
- it("summarization works", () => {
89
- const r = dictArr(...genericArr);
90
- expect(r.sum("cost")).toBe(60);
91
- });
92
-
93
- it("counting of non-required props works", () => {
94
- const r = dictArr(...genericArr);
95
- expect(r.count("color")).toBe(1);
96
- expect(r.count("cost")).toBe(2);
97
- });
98
-
99
- it("uniqueness", () => {
100
- const r = dictArr(...genericArr);
101
- const color = r.unique("color");
102
- const title = r.unique("title");
103
-
104
- expect(color.isUnique).toBeTruthy();
105
- expect(color.includedUndefined).toBeTruthy();
106
- expect(color.values).toEqual([undefined, "green"]);
107
- expect(title.isUnique).toBeFalsy();
108
- expect(title.values).toEqual(["one", "two"]);
109
- });
110
- });
@@ -1,82 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
-
3
- import { idLiteral, literal } from "../src/runtime";
4
- import { Equal, NotEqual, Expect, ExpectExtends, ExpectFalse } from "@type-challenges/utils";
5
-
6
- describe("literal enforcement", () => {
7
- it("idLiteral forces 'id' to literal number", () => {
8
- const t1 = { id: 1, message: "t1" };
9
- const t2 = { id: 2, message: "t2" };
10
- type T1 = typeof t1.id;
11
- type T2 = typeof t2.id;
12
-
13
- const l1 = idLiteral({ id: 1, message: "t1" });
14
- const l2 = idLiteral({ id: 2, message: "t2" });
15
- type L1 = typeof l1.id;
16
- type L2 = typeof l2.id;
17
-
18
- expect(typeof l1.id).toBe("number"); // run time type of "number"
19
- expect(typeof l2.id).toBe("number"); // run time type of "number"
20
-
21
- type cases = [
22
- Expect<Equal<T1, T2>>, // without using explicit cast to literal, TS sees as equivalent
23
- Expect<NotEqual<L1, L2>>, // TS types, are literals and therefore not equal
24
- Expect<NotEqual<L1, number>>,
25
- Expect<NotEqual<L2, number>>
26
- ];
27
- const typeTests: cases = [true, true, true, true];
28
- expect(typeTests).toBe(typeTests);
29
- });
30
-
31
- it("An array records from idLiteral() is typed as an array of 'id' literals", () => {
32
- const l1 = idLiteral({ id: 1, message: "t1" });
33
- const l2 = idLiteral({ id: 2, message: "t2" });
34
- const arr = [l1, l2];
35
- type L1 = typeof arr[0]["id"];
36
- type L2 = typeof arr[1]["id"];
37
- type NonIndexedId = 3;
38
-
39
- // run-time type is maintained
40
- for (const item of arr) {
41
- expect(typeof item.id).toBe("number");
42
- }
43
-
44
- // real test is literals being accumulated rather than being widened up to "number"
45
- type cases = [
46
- Expect<Equal<L1, L2>>,
47
- Expect<NotEqual<L1, NonIndexedId>>,
48
- Expect<NotEqual<L1, number>>,
49
- Expect<NotEqual<L2, number>>
50
- ];
51
- const typeTests: cases = [true, true, true, true];
52
- expect(typeTests).toBe(typeTests);
53
- });
54
-
55
- it("literal() creates narrow type definitions for all props on passed in object", () => {
56
- /** by default you get a wide definition of types */
57
- const wide = { foo: 1, bar: false, baz: "hi" };
58
- type Wide = typeof wide;
59
- /** but with the literal function we can force this to narrow */
60
- const narrow = literal({ foo: 1, bar: false, baz: "hi" });
61
- type Narrow = typeof narrow;
62
- /**
63
- * would be nice if this worked but it doesn't; once the type is set, it's set
64
- */
65
- const nope = literal(wide);
66
- type Nope = typeof nope;
67
-
68
- type cases = [
69
- Expect<Equal<Wide, { foo: number; bar: boolean; baz: string }>>,
70
- Expect<Equal<Narrow, { foo: 1; bar: false; baz: "hi" }>>,
71
- // Narrow _does_ extend the Wide definition
72
- Expect<ExpectExtends<Wide, Narrow>>,
73
- // but the opposite is not true
74
- ExpectFalse<ExpectExtends<Narrow, Wide>>,
75
- // now unfortunately, using literal() on a variable who's type
76
- // has already been inferred does not get us to Narrow
77
- Expect<Equal<Wide, Nope>>
78
- ];
79
- const cases: cases = [true, true, true, false, true];
80
- expect(cases).toBe(cases);
81
- });
82
- });
@@ -1,33 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
-
3
- import { Equal, Expect } from "@type-challenges/utils";
4
- import { AllCaps } from "src/types";
5
-
6
- describe("AllCaps<T> type utility", () => {
7
- it("finds AllCaps where it exists", () => {
8
- type T1 = AllCaps<"YUP">;
9
- type T2 = AllCaps<"YUP ">;
10
- type T3 = AllCaps<"YUP YUP YESSSSSSSSSSSSSS">;
11
-
12
- type cases = [Expect<Equal<T1, true>>, Expect<Equal<T2, true>>, Expect<Equal<T3, true>>];
13
- const c: cases = [true, true, true];
14
- expect(c).toBe(c);
15
- });
16
-
17
- it("correctly identifies the absence of AllCaps", () => {
18
- type T1 = AllCaps<"Nope">;
19
- type T2 = AllCaps<" noo nooo noooooooooooooo">;
20
-
21
- type cases = [Expect<Equal<T1, false>>, Expect<Equal<T2, false>>];
22
- const c: cases = [true, true];
23
- expect(c).toBe(c);
24
- });
25
-
26
- it("when passed a non literal string, returns 'unknown'", () => {
27
- type T1 = AllCaps<string>;
28
-
29
- type cases = [Expect<Equal<T1, "unknown">>];
30
- const c: cases = [true];
31
- expect(c).toBe(c);
32
- });
33
- });