inferred-types 0.33.1 → 0.33.3

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 (145) hide show
  1. package/.vscode/settings.json +1 -0
  2. package/dist/index.d.ts +1209 -1152
  3. package/dist/index.js +73 -182
  4. package/dist/index.mjs +70 -175
  5. package/package.json +16 -15
  6. package/src/{utility/errors → errors}/ReadOnlyViolation.ts +0 -0
  7. package/src/{utility/errors → errors}/index.ts +0 -0
  8. package/src/index.ts +1 -3
  9. package/src/{utility → runtime}/README.md +0 -0
  10. package/src/{utility → runtime}/api/api.ts +0 -0
  11. package/src/{utility → runtime}/api/index.ts +0 -0
  12. package/src/{utility/modelling → runtime/builders}/Model.ts +0 -0
  13. package/src/runtime/builders/url.ts +15 -0
  14. package/src/{utility/boolean-logic → runtime/combinators}/and.ts +0 -0
  15. package/src/{utility/boolean-logic → runtime/combinators}/filter.ts +0 -0
  16. package/src/{utility/boolean-logic → runtime/combinators}/index.ts +0 -0
  17. package/src/{utility/boolean-logic → runtime/combinators}/not.ts +0 -0
  18. package/src/{utility/boolean-logic → runtime/combinators}/or.ts +0 -0
  19. package/src/{utility → runtime}/createFnWithProps.ts +0 -0
  20. package/src/{utility → runtime}/dictionary/arrayToKeyLookup.ts +0 -0
  21. package/src/{utility → runtime}/dictionary/defineProperties.ts +0 -0
  22. package/src/{utility → runtime}/dictionary/dictArr.ts +0 -0
  23. package/src/{utility → runtime}/dictionary/dictionaryTransform.ts +0 -0
  24. package/src/{utility → runtime}/dictionary/entries.ts +0 -0
  25. package/src/{utility → runtime}/dictionary/index.ts +0 -0
  26. package/src/{utility → runtime}/dictionary/kv/dictToKv.ts +1 -1
  27. package/src/{utility → runtime}/dictionary/kv/filterDictArray.ts +1 -1
  28. package/src/{utility → runtime}/dictionary/kv/index.ts +0 -0
  29. package/src/{utility → runtime}/dictionary/kv/kv.ts +0 -0
  30. package/src/{utility → runtime}/dictionary/kv/kvToDict.ts +0 -0
  31. package/src/{utility → runtime}/dictionary/mapTo.ts +0 -0
  32. package/src/{utility → runtime}/dictionary/mapValues.ts +0 -0
  33. package/src/{utility → runtime}/dictionary/merge.ts +0 -0
  34. package/src/{utility → runtime}/dictionary/strArrayToDict.ts +0 -0
  35. package/src/{utility → runtime}/index.ts +1 -3
  36. package/src/{utility → runtime}/keys.ts +0 -0
  37. package/src/{utility → runtime}/lists/asArray.ts +0 -0
  38. package/src/{utility → runtime}/lists/groupBy.ts +0 -0
  39. package/src/{utility → runtime}/lists/index.ts +0 -0
  40. package/src/{utility → runtime}/literals/ExplicitFunction.ts +0 -0
  41. package/src/runtime/literals/Suggest.ts +19 -0
  42. package/src/{utility → runtime}/literals/arrayToObject.ts +0 -0
  43. package/src/runtime/literals/box.ts +77 -0
  44. package/src/{utility → runtime}/literals/defineType.ts +0 -0
  45. package/src/{utility → runtime}/literals/identity.ts +0 -0
  46. package/src/{utility → runtime}/literals/index.ts +2 -0
  47. package/src/{utility → runtime}/literals/literal.ts +0 -0
  48. package/src/{utility → runtime}/ruleset.ts +0 -0
  49. package/src/{utility → runtime}/runtime/README.md +0 -0
  50. package/src/{utility → runtime}/runtime/condition.ts +0 -0
  51. package/src/{utility → runtime}/runtime/index.ts +1 -2
  52. package/src/{utility → runtime}/runtime/type.ts +1 -1
  53. package/src/{utility → runtime}/runtime/withValue.ts +0 -0
  54. package/src/{utility → runtime}/state/Configurator.ts +0 -0
  55. package/src/{utility → runtime}/state/FluentConfigurator.ts +0 -0
  56. package/src/{utility → runtime}/state/index.ts +0 -0
  57. package/src/{utility/runtime → runtime/type-checks}/ifTypeOf.ts +0 -0
  58. package/src/{utility/runtime/conditions → runtime/type-checks}/index.ts +0 -0
  59. package/src/{utility/runtime/conditions → runtime/type-checks}/isArray.ts +0 -0
  60. package/src/{utility/runtime/conditions → runtime/type-checks}/isBoolean.ts +0 -0
  61. package/src/{utility/runtime/conditions → runtime/type-checks}/isFalse.ts +0 -0
  62. package/src/{utility/runtime/conditions → runtime/type-checks}/isFunction.ts +11 -2
  63. package/src/{utility/runtime/conditions → runtime/type-checks}/isNull.ts +0 -0
  64. package/src/{utility/runtime/conditions → runtime/type-checks}/isNumber.ts +0 -0
  65. package/src/{utility/runtime/conditions → runtime/type-checks}/isObject.ts +1 -1
  66. package/src/{utility/runtime/conditions → runtime/type-checks}/isString.ts +13 -5
  67. package/src/{utility/runtime/conditions → runtime/type-checks}/isSymbol.ts +0 -0
  68. package/src/{utility/runtime/conditions → runtime/type-checks}/isTrue.ts +1 -1
  69. package/src/{utility/runtime/conditions → runtime/type-checks}/isUndefined.ts +1 -1
  70. package/src/runtime/type-checks/startsWith.ts +109 -0
  71. package/src/{shared → runtime}/valueTypes.ts +0 -0
  72. package/src/types/FunctionType.ts +12 -2
  73. package/src/types/Mutable.ts +1 -1
  74. package/src/types/alphabetic/Url.ts +29 -0
  75. package/src/types/alphabetic/alpha-characters.ts +8 -0
  76. package/src/types/alphabetic/index.ts +1 -0
  77. package/src/types/dictionary/MapTo.ts +2 -2
  78. package/src/types/index.ts +2 -2
  79. package/src/types/lists/AfterFirst.ts +10 -0
  80. package/src/types/lists/First.ts +8 -0
  81. package/src/types/lists/FirstString.ts +4 -0
  82. package/src/types/lists/Split.ts +21 -0
  83. package/src/types/lists/index.ts +4 -0
  84. package/src/types/ruleset-types.ts +1 -1
  85. package/src/types/type-checks/EndsWith.ts +22 -0
  86. package/src/types/{TypeInfo → type-checks}/Extends.ts +0 -0
  87. package/src/types/{TypeInfo → type-checks}/Includes.ts +0 -0
  88. package/src/types/{TypeInfo → type-checks}/IsBooleanLiteral.ts +0 -0
  89. package/src/types/{TypeInfo → type-checks}/IsLiteral.ts +0 -0
  90. package/src/types/{TypeInfo → type-checks}/IsNumericLiteral.ts +0 -0
  91. package/src/types/{TypeInfo → type-checks}/IsScalar.ts +0 -0
  92. package/src/types/{TypeInfo → type-checks}/IsStringLiteral.ts +2 -6
  93. package/src/types/{TypeInfo → type-checks}/IsUndefined.ts +0 -0
  94. package/src/types/type-checks/StartsWith.ts +43 -0
  95. package/src/types/{TypeInfo → type-checks}/TypeDefault.ts +1 -1
  96. package/src/types/{TypeInfo → type-checks}/index.ts +4 -1
  97. package/src/types/{TypeInfo/IsObject.ts → type-checks/object.ts} +0 -0
  98. package/src/types/type-checks/string.ts +21 -0
  99. package/src/types/type-conversion/TupleToUnion.ts +1 -3
  100. package/tests/ExplicitFunction-spec.ts +1 -1
  101. package/tests/arrayToKeyLookup-spec.ts +1 -1
  102. package/tests/arrayToObject-spec.ts +1 -1
  103. package/tests/boolean-logic/boolean.spec.ts +1 -1
  104. package/tests/boolean-logic/filter.spec.ts +1 -1
  105. package/tests/defineType-spec.ts +1 -1
  106. package/tests/dictionary/Get.spec.ts +1 -1
  107. package/tests/dictionary/TypeDefault.test.ts +2 -2
  108. package/tests/dictionary/mapTo.test.ts +1 -1
  109. package/tests/dictionary/merge.test.ts +1 -1
  110. package/tests/dictionaryTransform-spec.ts +1 -1
  111. package/tests/ifTypeOf-spec.ts +3 -2
  112. package/tests/kv/dict-to-kv-and-back.spec.ts +2 -2
  113. package/tests/kv/entries-spec.ts +1 -1
  114. package/tests/kv/keys.spec.ts +1 -1
  115. package/tests/kv/kv-spec.ts +1 -1
  116. package/tests/lists/First.test.ts +43 -0
  117. package/tests/lists/Split.test.ts +29 -0
  118. package/tests/lists/asArray.test.ts +1 -1
  119. package/tests/lists/dictArr.test.ts +1 -1
  120. package/tests/literal-spec.ts +1 -1
  121. package/tests/{string-literals → literals}/AllCaps.spec.ts +0 -0
  122. package/tests/{string-literals → literals}/CamelCase.spec.ts +0 -0
  123. package/tests/{string-literals → literals}/Dasherize.spec.ts +0 -0
  124. package/tests/{string-literals → literals}/HasUppercase.spec.ts +0 -0
  125. package/tests/{string-literals → literals}/PascalCase.spec.ts +0 -0
  126. package/tests/{string-literals → literals}/SnakeCase.spec.ts +0 -0
  127. package/tests/literals/box.test.ts +77 -0
  128. package/tests/{string-literals → literals}/whitespace-capture.spec.ts +0 -0
  129. package/tests/mapValues-spec.ts +1 -1
  130. package/tests/runtime/condition.spec.ts +1 -1
  131. package/tests/runtime/if-is.spec.ts +158 -2
  132. package/tests/runtime/type.spec.ts +1 -1
  133. package/tests/strArrayToDict-spec.ts +1 -1
  134. package/tests/withValue.spec.ts +1 -1
  135. package/vitest.config.ts +2 -5
  136. package/src/Mutation/MutationFunction.ts +0 -26
  137. package/src/Mutation/MutationIdentity.ts +0 -36
  138. package/src/Mutation/index.ts +0 -14
  139. package/src/shared/README.md +0 -3
  140. package/src/shared/index.ts +0 -15
  141. package/src/shared/randomString.ts +0 -5
  142. package/src/shared/uuid.ts +0 -5
  143. package/src/types/First.ts +0 -4
  144. package/src/utility/modelling/index.ts +0 -12
  145. package/tests/MutationIdentity-spec.ts +0 -25
@@ -0,0 +1,22 @@
1
+ import { IfStringLiteral } from "src/types/type-checks";
2
+
3
+ /**
4
+ * **EndsWith**<T,U>
5
+ *
6
+ * A type utility which checks whether `T` _ends with_ the string literal `U`.
7
+ *
8
+ * If both `T` and `U` are string literals then the type system will resolve
9
+ * to a literal `true` or `false` but if either is not a literal that it will
10
+ * just resolve to `boolean` as the value can not be known at design time..
11
+ */
12
+ export type EndsWith<T extends unknown, U extends unknown> = T extends string
13
+ ? U extends string
14
+ ? T extends `${string}${U}`
15
+ ? IfStringLiteral<
16
+ T, //
17
+ IfStringLiteral<U, true, boolean>,
18
+ boolean
19
+ >
20
+ : IfStringLiteral<T, false, boolean>
21
+ : false
22
+ : false;
File without changes
File without changes
File without changes
File without changes
@@ -4,15 +4,11 @@
4
4
  * Type utility which returns true/false if the string a _string literal_ versus
5
5
  * just the _string_ type.
6
6
  */
7
- export type IsStringLiteral<T> = T extends string
8
- ? string extends T ? false : true
9
- : false;
7
+ export type IsStringLiteral<T> = [T] extends [string] ? (string extends T ? false : true) : false;
10
8
 
11
9
  /**
12
10
  * **IfStringLiteral**
13
11
  *
14
12
  * Branch utility which returns `IF` type when `T` is a string literal and `ELSE` otherwise
15
13
  */
16
- export type IfStringLiteral<T extends string, IF, ELSE> = IsStringLiteral<T> extends true
17
- ? IF
18
- : ELSE;
14
+ export type IfStringLiteral<T, IF, ELSE> = [IsStringLiteral<T>] extends [true] ? IF : ELSE;
@@ -0,0 +1,43 @@
1
+ import { IfStringLiteral } from "src/types/type-checks";
2
+ import { Narrowable } from "../Narrowable";
3
+ /**
4
+ * **StartsWith**<TValue, TStartsWith>
5
+ *
6
+ * A type utility which checks whether `T` _starts with_ the string literal `U`.
7
+ *
8
+ * If both `T` and `U` are string literals then the type system will resolve
9
+ * to a literal `true` or `false` but if either is not a literal that it will
10
+ * just resolve to `boolean` as the value can not be known at design time..
11
+ */
12
+ export type StartsWith<TValue extends unknown, TStartsWith extends unknown> = TValue extends string
13
+ ? TStartsWith extends string
14
+ ? TValue extends `${TStartsWith}${string}`
15
+ ? IfStringLiteral<
16
+ TValue, //
17
+ IfStringLiteral<TStartsWith, true, boolean>,
18
+ boolean
19
+ >
20
+ : IfStringLiteral<TValue, false, boolean>
21
+ : false
22
+ : false;
23
+
24
+ /**
25
+ * **IfStartsWith**<TValue, TStartsWith, IF, ELSE, MAYBE>
26
+ *
27
+ * Type utility which converts type to `IF` type _if_ TValue _starts with_ `TStartsWith` but
28
+ * otherwise converts type to `ELSE`.
29
+ *
30
+ * Note, that there is also an optional `MAYBE` type
31
+ * which can be stated for cases where TValue or TStartsWith _might_ be the wider `string`
32
+ * type and therefore the type is unknown at design time.
33
+ */
34
+ export type IfStartsWith<
35
+ TValue extends unknown,
36
+ TStartsWith extends unknown,
37
+ IF extends Narrowable,
38
+ ELSE extends Narrowable
39
+ > = StartsWith<TValue, TStartsWith> extends true
40
+ ? IF
41
+ : StartsWith<TValue, TStartsWith> extends false
42
+ ? ELSE
43
+ : IF | ELSE;
@@ -1,4 +1,4 @@
1
- import { IsObject } from "src/types/TypeInfo";
1
+ import { IsObject } from "src/types/type-checks";
2
2
  import { SimplifyObject } from "../SimplifyObject";
3
3
  import { IfExtends } from "./Extends";
4
4
  import { IfOptionalLiteral } from "./IsLiteral";
@@ -4,6 +4,9 @@ export * from "./IsNumericLiteral";
4
4
  export * from "./IsScalar";
5
5
  export * from "./IsStringLiteral";
6
6
  export * from "./IsLiteral";
7
+ export * from "./IsUndefined";
7
8
  export * from "./Extends";
8
9
  export * from "./TypeDefault";
9
- export * from "./IsObject";
10
+ export * from "./object";
11
+ export * from "./StartsWith";
12
+ export * from "./EndsWith";
@@ -0,0 +1,21 @@
1
+ import { Narrowable } from "src/types";
2
+
3
+ /**
4
+ * **IsString**
5
+ *
6
+ * Type utility which returns true/false based on whether `T` is a
7
+ * string (wide or narrow).
8
+ */
9
+ export type IsString<T> = T extends string ? true : false;
10
+
11
+ /**
12
+ * **IfString**
13
+ *
14
+ * Type utility which determines if `T` is a _string_ (wide or narrow) and
15
+ * returns `IF` type if it is, otherwise returns the type `ELSE`.
16
+ */
17
+ export type IfString<
18
+ T extends Narrowable, //
19
+ IF extends Narrowable,
20
+ ELSE extends Narrowable
21
+ > = IsString<T> extends true ? IF : ELSE;
@@ -1,5 +1,3 @@
1
- import { Mutable } from "../Mutable";
2
-
3
1
  /**
4
2
  * Converts a Tuple type into a _union_ of the tuple elements
5
3
  * ```ts
@@ -8,4 +6,4 @@ import { Mutable } from "../Mutable";
8
6
  * type U = TupleToUnion<typeof arr>;
9
7
  * ```
10
8
  */
11
- export type TupleToUnion<T> = Mutable<T> extends any[] ? Mutable<T>[number] : never;
9
+ export type TupleToUnion<T> = T extends readonly any[] ? T[number] : never;
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
- import { ExplicitFunction } from "../src/utility";
3
+ import { ExplicitFunction } from "../src/runtime";
4
4
  import type { Expect, Equal } from "@type-challenges/utils";
5
5
 
6
6
  describe("ExplicitFunction()", () => {
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
3
  import { Equal, Expect } from "@type-challenges/utils";
4
- import { arrayToKeyLookup } from "../src/utility";
4
+ import { arrayToKeyLookup } from "../src/runtime";
5
5
 
6
6
  describe("arrayToKeyLookup()", () => {
7
7
  it("simple string array is converted", () => {
@@ -8,7 +8,7 @@ import {
8
8
  UniqueDictionary,
9
9
  defineType,
10
10
  keys,
11
- } from "../src/utility";
11
+ } from "../src/runtime";
12
12
 
13
13
  const foo = { name: "foo", age: 123, color: "red" } as const;
14
14
  const foo2 = { name: "foo", age: 44, color: "orange" } as const;
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
  // import type { Equal, Expect } from "@type-challenges/utils";
3
- import { and, filter } from "src/utility";
3
+ import { and, filter } from "src/runtime";
4
4
 
5
5
  describe("boolean logic", () => {
6
6
  it("AND operation", () => {
@@ -1,4 +1,4 @@
1
- import { filter } from "src/utility";
1
+ import { filter } from "src/runtime";
2
2
  import { Equal, Expect } from "@type-challenges/utils";
3
3
  import { describe, it, expect } from "vitest";
4
4
 
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
2
2
 
3
3
  import type { Expect, Equal } from "@type-challenges/utils";
4
4
  import { ExpectExtends } from "../src/types";
5
- import { defineType } from "../src/utility";
5
+ import { defineType } from "../src/runtime";
6
6
 
7
7
  describe("inferredType() utility", () => {
8
8
  it("only specify a wide type", () => {
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
2
2
 
3
3
  import { Equal, Expect } from "@type-challenges/utils";
4
4
  import { Get } from "src/types";
5
- import { defineType } from "src/utility";
5
+ import { defineType } from "src/runtime";
6
6
 
7
7
  describe("Get<T, K> type utility", () => {
8
8
  it("Get<T,K> works with literals and wide types", () => {
@@ -1,7 +1,7 @@
1
1
  import { describe, it } from "vitest";
2
2
  import { Equal, Expect } from "@type-challenges/utils";
3
- import { TypeDefault } from "src/types/TypeInfo/TypeDefault";
4
- import { literal } from "src/utility/literals";
3
+ import { TypeDefault } from "src/types/type-checks/TypeDefault";
4
+ import { literal } from "src/runtime/literals";
5
5
 
6
6
  describe("TypeDefault<T,D>", () => {
7
7
  it("T/D as dictionary", () => {
@@ -16,7 +16,7 @@ import {
16
16
  DEFAULT_MANY_TO_ONE_MAPPING,
17
17
  DEFAULT_ONE_TO_MANY_MAPPING,
18
18
  mapTo,
19
- } from "src/utility/dictionary/mapTo";
19
+ } from "src/runtime/dictionary/mapTo";
20
20
 
21
21
  type I = { title: string; color: string; products: string[] };
22
22
  const i: I = { title: "Test", color: "green", products: ["foo", "bar", "baz"] };
@@ -1,5 +1,5 @@
1
1
  import { Equal, Expect } from "@type-challenges/utils";
2
- import { merge } from "src/utility/dictionary/merge";
2
+ import { merge } from "src/runtime/dictionary/merge";
3
3
  import { describe, expect, it } from "vitest";
4
4
 
5
5
  describe("merge() utility", () => {
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { dictionaryTransform, ExplicitFunction } from "../src/utility";
2
+ import { dictionaryTransform, ExplicitFunction } from "../src/runtime";
3
3
  import { Expect, Equal, NotEqual, ExpectExtends, ExpectFalse } from "@type-challenges/utils";
4
4
  import { ToFluent, Transformer } from "../src/types";
5
5
 
@@ -2,7 +2,8 @@ import { describe, it, expect } from "vitest";
2
2
 
3
3
  /* eslint-disable @typescript-eslint/no-unused-vars */
4
4
  import { Expect, Equal } from "@type-challenges/utils";
5
- import { ifTypeOf, defineType, literal } from "../src/utility";
5
+ import { defineType, literal } from "../src/runtime";
6
+ import { ifTypeOf } from "src/runtime/type-checks/ifTypeOf";
6
7
 
7
8
  describe("ifTypeOf() utility", () => {
8
9
  it("base validation with extends() returns true/false", () => {
@@ -142,7 +143,7 @@ describe("ifTypeOf() utility", () => {
142
143
  // literal types and broader types; this is not hard to express with types
143
144
  // but it makes our approach much more awkward and the API much more cumbersome
144
145
 
145
- // here we see a type that represents this challange but how it fails with
146
+ // here we see a type that represents this challenge but how it fails with
146
147
  // with the runtime
147
148
 
148
149
  const literal = { foo: 1 } as const;
@@ -1,9 +1,9 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
3
  import { Equal, Expect, NotEqual } from "@type-challenges/utils";
4
- import { dictToKv, kvToDict } from "src/utility/dictionary";
4
+ import { dictToKv, kvToDict } from "src/runtime/dictionary";
5
5
  import { DictFromKv } from "src/types/kv";
6
- import { keys } from "src/utility";
6
+ import { keys } from "src/runtime";
7
7
 
8
8
  describe("dictToKv()", () => {
9
9
  it.skip("basic structure is correct when forcing to Tuple structure", () => {
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
3
  import type { Expect, NotEqual, Equal, ExpectExtends } from "@type-challenges/utils";
4
- import { entries } from "src/utility";
4
+ import { entries } from "src/runtime";
5
5
 
6
6
  describe("entries() => ", () => {
7
7
  it("literal types are retained", () => {
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
2
2
 
3
3
  import { Keys } from "src/types/Keys";
4
4
  import type { Expect, Equal } from "@type-challenges/utils";
5
- import { defineType, keys } from "src/utility";
5
+ import { defineType, keys } from "src/runtime";
6
6
 
7
7
  describe("Keys<T>", () => {
8
8
  it("Keys<T> is shorthand for keyof T", () => {
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
- import { keys, kv } from "src/utility";
3
+ import { keys, kv } from "src/runtime";
4
4
 
5
5
  describe("kv utils", () => {
6
6
  it("simple assignment works with strong literal support", () => {
@@ -0,0 +1,43 @@
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
+ });
@@ -0,0 +1,29 @@
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,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { asArray } from "src/utility";
2
+ import { asArray } from "src/runtime";
3
3
  import { Equal, Expect } from "@type-challenges/utils";
4
4
 
5
5
  describe("asArray() function", () => {
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import type { Expect, Equal } from "@type-challenges/utils";
3
- import { dictArr, keys, literal } from "src/utility";
3
+ import { dictArr, keys, literal } from "src/runtime";
4
4
 
5
5
  type O = {
6
6
  id: number;
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
- import { idLiteral, literal } from "../src/utility";
3
+ import { idLiteral, literal } from "../src/runtime";
4
4
  import { Equal, NotEqual, Expect, ExpectExtends, ExpectFalse } from "@type-challenges/utils";
5
5
 
6
6
  describe("literal enforcement", () => {
@@ -0,0 +1,77 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { Equal, Expect } from "@type-challenges/utils";
3
+ import { Box, box, BoxedFnParams, BoxValue } from "src/runtime";
4
+ import { First } from "src/types/lists/First";
5
+
6
+ // [Instantiation Expressions](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#instantiation-expressions)
7
+
8
+ describe("boxing / unboxing", () => {
9
+ // it("NarrowBox<B,N> utility", () => {
10
+ // const fn = <T extends string>(i: T) => `Hello ${i}` as const;
11
+ // const b = box(fn);
12
+ // const b2 = b.narrow<["foo" | "bar"]>();
13
+ // const b3 = b2("foo");
14
+
15
+ // type B = typeof b;
16
+ // });
17
+
18
+ it("box a function with generic", () => {
19
+ const fn = <T extends string>(i: T) => `Hello ${i}` as const;
20
+ const b = box(fn);
21
+ const ub = b.unbox();
22
+ type UB = typeof ub;
23
+ const unboxedFn = b.unbox()("foo");
24
+ const unboxedFn2 = b.unbox()("foo" as string);
25
+ type UBF = typeof unboxedFn;
26
+ type UBF2 = typeof unboxedFn2;
27
+
28
+ const bn = box(42);
29
+ type BN = typeof bn;
30
+ const rn = bn.unbox();
31
+ type RN = typeof rn;
32
+ const rn2 = bn.value;
33
+ type RN2 = typeof rn2;
34
+
35
+ type Hybrid = 42 | 56 | typeof fn;
36
+ const h = box(42 as Hybrid);
37
+ type H = typeof h;
38
+ type HV = H["value"];
39
+
40
+ // runtime
41
+ expect(typeof b).toBe("object");
42
+ expect(typeof ub).toBe("function");
43
+ expect(unboxedFn).toBe("Hello foo");
44
+
45
+ expect(rn).toBe(42);
46
+ expect(rn2).toBe(42);
47
+
48
+ // type tests
49
+ type B = typeof b;
50
+ type BV = BoxValue<B>;
51
+ type BF = First<BoxedFnParams<B>>;
52
+
53
+ type cases = [
54
+ // FUNCTIONS
55
+ Expect<Equal<B, Box<typeof fn>>>,
56
+ Expect<Equal<BV, typeof fn>>, //
57
+ Expect<Equal<BF, string>>,
58
+ /** unboxing fn results in same fn including generics */
59
+ Expect<Equal<UB, typeof fn>>,
60
+ /** generic for fn provides strong literal type after unboxing */
61
+ Expect<Equal<UBF, "Hello foo">>,
62
+ /** generic still provides some strong typing when a wide type is passed in */
63
+ Expect<Equal<UBF2, `Hello ${string}`>>,
64
+
65
+ // NUMBER BOXes
66
+ Expect<Equal<BN, Box<42>>>,
67
+ /** unboxing preserves numeric literal */
68
+ Expect<Equal<RN, 42>>,
69
+ /** can pick off the value prop for same type */
70
+ Expect<Equal<RN2, 42>>,
71
+
72
+ // HYBRID
73
+ Expect<Equal<HV, Hybrid>>
74
+ ];
75
+ const cases: cases = [true, true, true, true, true, true, true, true, true, true];
76
+ });
77
+ });
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
 
3
- import { mapValues, literal } from "../src/utility";
3
+ import { mapValues, literal } from "../src/runtime";
4
4
  import type { Expect, Equal, ExpectFalse } from "@type-challenges/utils";
5
5
 
6
6
  describe("mapValues() utility", () => {
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { condition, isFunction, isTrue } from "src/utility";
2
+ import { condition, isFunction, isTrue } from "src/runtime";
3
3
 
4
4
  describe("condition() utility", () => {
5
5
  it("basic type checks through condition abstraction", () => {