lay-sing 0.3.0 → 0.4.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 (125) hide show
  1. package/README.md +17 -17
  2. package/esm/main/expect/index.d.ts +31 -0
  3. package/esm/main/expect/index.d.ts.map +1 -0
  4. package/esm/main/expect/index.js +2 -0
  5. package/esm/main/expect/index.js.map +1 -0
  6. package/esm/main/expect/to/be.d.ts +23 -0
  7. package/esm/main/expect/to/be.d.ts.map +1 -0
  8. package/esm/main/expect/to/be.js +2 -0
  9. package/esm/main/expect/to/be.js.map +1 -0
  10. package/esm/main/expect/to/equal.d.ts +26 -0
  11. package/esm/main/expect/to/equal.d.ts.map +1 -0
  12. package/esm/main/expect/to/equal.js +2 -0
  13. package/esm/main/expect/to/equal.js.map +1 -0
  14. package/esm/main/expect/to/extend.d.ts +31 -0
  15. package/esm/main/expect/to/extend.d.ts.map +1 -0
  16. package/esm/main/expect/to/extend.js +2 -0
  17. package/esm/main/expect/to/extend.js.map +1 -0
  18. package/esm/main/expect/to/have-key.d.ts +38 -0
  19. package/esm/main/expect/to/have-key.d.ts.map +1 -0
  20. package/esm/main/expect/to/have-key.js +2 -0
  21. package/esm/main/expect/to/have-key.js.map +1 -0
  22. package/esm/main/expect/to/index.d.ts +13 -0
  23. package/esm/main/expect/to/index.d.ts.map +1 -0
  24. package/esm/main/expect/to/index.js +2 -0
  25. package/esm/main/expect/to/index.js.map +1 -0
  26. package/esm/main/expect/to/proper-extends.d.ts +21 -0
  27. package/esm/main/expect/to/proper-extends.d.ts.map +1 -0
  28. package/esm/main/expect/to/proper-extends.js +2 -0
  29. package/esm/main/expect/to/proper-extends.js.map +1 -0
  30. package/esm/main/index.d.ts +10 -8
  31. package/esm/main/index.d.ts.map +1 -1
  32. package/esm/main/index.js +20 -3
  33. package/esm/main/index.js.map +1 -1
  34. package/esm/utils/compare/exact.d.ts +8 -8
  35. package/esm/utils/compare/exact.js.map +1 -1
  36. package/esm/utils/index.d.ts +1 -0
  37. package/esm/utils/index.d.ts.map +1 -1
  38. package/esm/utils/index.js +1 -0
  39. package/esm/utils/index.js.map +1 -1
  40. package/esm/utils/logic/assert.d.ts +3 -3
  41. package/esm/utils/logic/assert.js.map +1 -1
  42. package/esm/utils/logic/switch.d.ts +1 -1
  43. package/esm/utils/logic/switch.js.map +1 -1
  44. package/esm/utils/misc.d.ts +34 -0
  45. package/esm/utils/misc.d.ts.map +1 -0
  46. package/esm/utils/misc.js +2 -0
  47. package/esm/utils/misc.js.map +1 -0
  48. package/esm/utils/object/keys.d.ts +12 -12
  49. package/esm/utils/object/keys.js.map +1 -1
  50. package/esm/utils/object/pick.d.ts +1 -1
  51. package/esm/utils/object/pick.js.map +1 -1
  52. package/esm/utils/object/props.d.ts +1 -1
  53. package/esm/utils/object/props.js.map +1 -1
  54. package/esm/utils/tuple/append.d.ts +2 -2
  55. package/esm/utils/tuple/append.js.map +1 -1
  56. package/esm/utils/tuple/concat.d.ts +2 -2
  57. package/esm/utils/tuple/concat.js.map +1 -1
  58. package/esm/utils/tuple/includes.d.ts +3 -3
  59. package/esm/utils/tuple/includes.js.map +1 -1
  60. package/package.json +1 -1
  61. package/script/main/expect/index.d.ts +31 -0
  62. package/script/main/expect/index.d.ts.map +1 -0
  63. package/script/main/{expect.js → expect/index.js} +1 -1
  64. package/script/main/expect/index.js.map +1 -0
  65. package/script/main/expect/to/be.d.ts +23 -0
  66. package/script/main/expect/to/be.d.ts.map +1 -0
  67. package/script/main/expect/to/be.js +3 -0
  68. package/script/main/expect/to/be.js.map +1 -0
  69. package/script/main/expect/to/equal.d.ts +26 -0
  70. package/script/main/expect/to/equal.d.ts.map +1 -0
  71. package/script/main/expect/to/equal.js +3 -0
  72. package/script/main/expect/to/equal.js.map +1 -0
  73. package/script/main/expect/to/extend.d.ts +31 -0
  74. package/script/main/expect/to/extend.d.ts.map +1 -0
  75. package/script/main/expect/to/extend.js +3 -0
  76. package/script/main/expect/to/extend.js.map +1 -0
  77. package/script/main/expect/to/have-key.d.ts +38 -0
  78. package/script/main/expect/to/have-key.d.ts.map +1 -0
  79. package/script/main/expect/to/have-key.js +3 -0
  80. package/script/main/expect/to/have-key.js.map +1 -0
  81. package/script/main/expect/to/index.d.ts +13 -0
  82. package/script/main/expect/to/index.d.ts.map +1 -0
  83. package/script/main/expect/to/index.js +3 -0
  84. package/script/main/expect/to/index.js.map +1 -0
  85. package/script/main/expect/to/proper-extends.d.ts +21 -0
  86. package/script/main/expect/to/proper-extends.d.ts.map +1 -0
  87. package/script/main/expect/to/proper-extends.js +3 -0
  88. package/script/main/expect/to/proper-extends.js.map +1 -0
  89. package/script/main/index.d.ts +10 -8
  90. package/script/main/index.d.ts.map +1 -1
  91. package/script/main/index.js +21 -5
  92. package/script/main/index.js.map +1 -1
  93. package/script/utils/compare/exact.d.ts +8 -8
  94. package/script/utils/compare/exact.js.map +1 -1
  95. package/script/utils/index.d.ts +1 -0
  96. package/script/utils/index.d.ts.map +1 -1
  97. package/script/utils/index.js +1 -0
  98. package/script/utils/index.js.map +1 -1
  99. package/script/utils/logic/assert.d.ts +3 -3
  100. package/script/utils/logic/assert.js.map +1 -1
  101. package/script/utils/logic/switch.d.ts +1 -1
  102. package/script/utils/logic/switch.js.map +1 -1
  103. package/script/utils/misc.d.ts +34 -0
  104. package/script/utils/misc.d.ts.map +1 -0
  105. package/script/utils/misc.js +3 -0
  106. package/script/utils/misc.js.map +1 -0
  107. package/script/utils/object/keys.d.ts +12 -12
  108. package/script/utils/object/keys.js.map +1 -1
  109. package/script/utils/object/pick.d.ts +1 -1
  110. package/script/utils/object/pick.js.map +1 -1
  111. package/script/utils/object/props.d.ts +1 -1
  112. package/script/utils/object/props.js.map +1 -1
  113. package/script/utils/tuple/append.d.ts +2 -2
  114. package/script/utils/tuple/append.js.map +1 -1
  115. package/script/utils/tuple/concat.d.ts +2 -2
  116. package/script/utils/tuple/concat.js.map +1 -1
  117. package/script/utils/tuple/includes.d.ts +3 -3
  118. package/script/utils/tuple/includes.js.map +1 -1
  119. package/esm/main/expect.d.ts +0 -293
  120. package/esm/main/expect.d.ts.map +0 -1
  121. package/esm/main/expect.js +0 -2
  122. package/esm/main/expect.js.map +0 -1
  123. package/script/main/expect.d.ts +0 -293
  124. package/script/main/expect.d.ts.map +0 -1
  125. package/script/main/expect.js.map +0 -1
package/README.md CHANGED
@@ -9,12 +9,12 @@ TypeScript utilities for compile-time type testing and utility types
9
9
 
10
10
  ```ts
11
11
  // They do nothing at runtime
12
- expect<never>().toBe<never>().success
13
- expect<never>().toBeNever // alias for the above
14
- expect<never>().toBe<'should fail'>().fail
12
+ expect<never>().to.be<never>().pass
13
+ expect<never>().to.be.never // alias for the above
14
+ expect<never>().to.be<'should fail'>().fail
15
15
 
16
- // Type Error: Property 'success' does not exist on type '{ fail: void; }'.
17
- expect<never>().toBe<'should fail'>().success
16
+ // Type Error: Property 'pass' does not exist on type '{ fail: void; }'.
17
+ expect<never>().to.be<'should fail'>().pass
18
18
  // ^^^^^^^
19
19
  ```
20
20
 
@@ -84,11 +84,11 @@ The main module provides utilities for **compile-time** type validation. These u
84
84
  A typical type test statement follows this pattern:
85
85
 
86
86
  ```ts
87
- expect<ActualType>().toBe<ExpectedType>().success
87
+ expect<ActualType>().to.be<ExpectedType>().pass
88
88
  ```
89
89
 
90
90
  - It starts with a function call like `expect<T>()` or `compare<T, U>()`
91
- - It ends with a property like `.success` or `.fail`
91
+ - It ends with a property like `.pass` or `.fail`
92
92
  - Type error occurs only if the assertion fails
93
93
 
94
94
  > [!CAUTION]
@@ -96,8 +96,8 @@ expect<ActualType>().toBe<ExpectedType>().success
96
96
  > Only statements ending with property access are type assertions. Without property access, type error may never occur:
97
97
  >
98
98
  > ```diff
99
- > - expect<true>().toBe<false>() // Type error never occur
100
- > + expect<true>().toBe<false>().success // Type Error: Property 'success' does not exist on type '{ fail: void; }'.
99
+ > - expect<true>().to.be<false>() // Type error never occur
100
+ > + expect<true>().to.be<false>().pass // Type Error: Property 'pass' does not exist on type '{ fail: void; }'.
101
101
  > ```
102
102
 
103
103
  At runtime, the function always returns the `NOOP` object, which performs **no operation**. It can be accessed, called, or chained indefinitely without throwing errors.
@@ -106,26 +106,26 @@ At runtime, the function always returns the `NOOP` object, which performs **no o
106
106
 
107
107
  ```ts
108
108
  // Passes only if A and B are identical
109
- expect<keyof { a: 2 }>().toBe<'a'>().success
109
+ expect<keyof { a: 2 }>().to.be<'a'>().pass
110
110
 
111
111
  // Passes if A extends B
112
- expect<12138>().toExtend<number>().success
112
+ expect<12138>().to.extend<number>().pass
113
113
 
114
114
  // Passes if mutually assignable
115
- expect<{ a: 1; b: 2 }>().toEqual<{ a: 1 } & { b: 2 }>().success
115
+ expect<{ a: 1; b: 2 }>().to.equal<{ a: 1 } & { b: 2 }>().pass
116
116
 
117
117
  // Test property existence
118
- expect<{ name: string }>().toHaveKey<'name'>().success
118
+ expect<{ name: string }>().to.haveKey<'name'>().pass
119
119
  ```
120
120
 
121
121
  Aliases:
122
122
 
123
123
  ```ts
124
- expect<never>().toBe<never>().success
125
- expect<never>().toBeNever
124
+ expect<never>().to.be<never>().pass
125
+ expect<never>().to.be.never
126
126
 
127
- expect<'hello'>().toExtend<string>().success
128
- expect<'hello'>().toExtendString
127
+ expect<'hello'>().to.extend<string>().pass
128
+ expect<'hello'>().to.extend.string
129
129
  ```
130
130
 
131
131
  #### NOOP
@@ -0,0 +1,31 @@
1
+ import type { Exact } from '../../utils/index.js';
2
+ import type { To } from './to/index.js';
3
+ /**
4
+ * Represents the result of a type assertion based on a boolean condition.
5
+ *
6
+ * - If `true`, the result has a `pass` property;
7
+ * - If `false`, the result has a `fail` property;
8
+ * - Otherwise, the result is `never`
9
+ *
10
+ * @template B The boolean condition result (true or false)
11
+ * @template R The type of the result value (default is void)
12
+ */
13
+ export type TypeAssertionResult<B extends boolean, R = void> = Exact<B, never> extends true ? never : [boolean] extends [B] ? never : [B] extends [true] ? {
14
+ /**
15
+ * This field exist only when this type assertion succeed
16
+ *
17
+ * If you expect this assertion to fail, use `.fail`
18
+ */
19
+ pass: R;
20
+ } : [B] extends [false] ? {
21
+ /**
22
+ * This field exist only when this type assertion failed
23
+ *
24
+ * If you expect this assertion to pass, use `.pass`
25
+ */
26
+ fail: R;
27
+ } : never;
28
+ export type ExpectType<T> = {
29
+ to: To<T>;
30
+ };
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/main/expect/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAEvC;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,IAAI,GAAG,KAAK,GAC/F,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,GAC7B,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;IACnB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAA;CACR,GACD,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG;IACpB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAA;CACR,GACD,KAAK,CAAA;AAET,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;CACV,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/main/expect/index.ts"],"names":[],"mappings":"","sourcesContent":["import type { Exact } from '../../utils/index.js'\nimport type { To } from './to/index.js'\n\n/**\n * Represents the result of a type assertion based on a boolean condition.\n *\n * - If `true`, the result has a `pass` property;\n * - If `false`, the result has a `fail` property;\n * - Otherwise, the result is `never`\n *\n * @template B The boolean condition result (true or false)\n * @template R The type of the result value (default is void)\n */\nexport type TypeAssertionResult<B extends boolean, R = void> = Exact<B, never> extends true ? never\n : [boolean] extends [B] ? never\n : [B] extends [true] ? {\n /**\n * This field exist only when this type assertion succeed\n *\n * If you expect this assertion to fail, use `.fail`\n */\n pass: R\n }\n : [B] extends [false] ? {\n /**\n * This field exist only when this type assertion failed\n *\n * If you expect this assertion to pass, use `.pass`\n */\n fail: R\n }\n : never\n\nexport type ExpectType<T> = {\n to: To<T>\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import type { Exact, If } from '../../../utils/index.js';
2
+ import type { TypeAssertionResult } from '../index.js';
3
+ export type Be<T> = {
4
+ <U>(): TypeAssertionResult<Exact<T, U>>;
5
+ <U>(_: U): TypeAssertionResult<Exact<T, U>>;
6
+ } & If<Exact<T, any>, {
7
+ any: void;
8
+ }, {}> & If<Exact<T, never>, {
9
+ never: void;
10
+ }, {}> & If<Exact<T, unknown>, {
11
+ unknown: void;
12
+ }, {}> & If<Exact<T, void>, {
13
+ void: void;
14
+ }, {}> & If<Exact<T, null>, {
15
+ null: void;
16
+ }, {}> & If<Exact<T, undefined>, {
17
+ undefined: void;
18
+ }, {}> & If<Exact<T, true>, {
19
+ true: void;
20
+ }, {}> & If<Exact<T, false>, {
21
+ false: void;
22
+ }, {}>;
23
+ //# sourceMappingURL=be.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"be.d.ts","sourceRoot":"","sources":["../../../../src/main/expect/to/be.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,MAAM,EAAE,CAAC,CAAC,IACZ;IACA,CAAC,CAAC,KAAK,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CAC5C,GACC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GACpC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GACxC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GAC5C,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GACtC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GACtC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE;IAAE,SAAS,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GAChD,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GACtC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=be.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"be.js","sourceRoot":"","sources":["../../../../src/main/expect/to/be.ts"],"names":[],"mappings":"","sourcesContent":["import type { Exact, If } from '../../../utils/index.js'\nimport type { TypeAssertionResult } from '../index.js'\n\nexport type Be<T> =\n & {\n <U>(): TypeAssertionResult<Exact<T, U>>\n <U>(_: U): TypeAssertionResult<Exact<T, U>>\n }\n & If<Exact<T, any>, { any: void }, {}>\n & If<Exact<T, never>, { never: void }, {}>\n & If<Exact<T, unknown>, { unknown: void }, {}>\n & If<Exact<T, void>, { void: void }, {}>\n & If<Exact<T, null>, { null: void }, {}>\n & If<Exact<T, undefined>, { undefined: void }, {}>\n & If<Exact<T, true>, { true: void }, {}>\n & If<Exact<T, false>, { false: void }, {}>\n"]}
@@ -0,0 +1,26 @@
1
+ import type { MutuallyAssignable } from '../../../utils/index.js';
2
+ import type { TypeAssertionResult } from '../index.js';
3
+ export type Equal<T> = {
4
+ /**
5
+ * Tests if the current type is mutually assignable with the provided type U.
6
+ *
7
+ * It's like:
8
+ *
9
+ * ```ts ignore
10
+ * [T] extends [U] ? [U] extends [T] ? Yes : No : No
11
+ * ```
12
+ *
13
+ * @template U The type to compare with
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { expect } from '@leawind/lay-sing'
18
+ *
19
+ * expect<{ a: 1; b: 2 }>().to.equal<{ a: 1 } & { b: 2 }>().pass
20
+ * expect<1>().to.equal<1 | 2>().fail
21
+ * ```
22
+ */
23
+ <U>(): TypeAssertionResult<MutuallyAssignable<T, U>>;
24
+ <U>(_: U): TypeAssertionResult<MutuallyAssignable<T, U>>;
25
+ };
26
+ //# sourceMappingURL=equal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equal.d.ts","sourceRoot":"","sources":["../../../../src/main/expect/to/equal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI;IACrB;;;;;;;;;;;;;;;;;;OAkBG;IACH,CAAC,CAAC,KAAK,mBAAmB,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACpD,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CACzD,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=equal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equal.js","sourceRoot":"","sources":["../../../../src/main/expect/to/equal.ts"],"names":[],"mappings":"","sourcesContent":["import type { MutuallyAssignable } from '../../../utils/index.js'\nimport type { TypeAssertionResult } from '../index.js'\n\nexport type Equal<T> = {\n /**\n * Tests if the current type is mutually assignable with the provided type U.\n *\n * It's like:\n *\n * ```ts ignore\n * [T] extends [U] ? [U] extends [T] ? Yes : No : No\n * ```\n *\n * @template U The type to compare with\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<{ a: 1; b: 2 }>().to.equal<{ a: 1 } & { b: 2 }>().pass\n * expect<1>().to.equal<1 | 2>().fail\n * ```\n */\n <U>(): TypeAssertionResult<MutuallyAssignable<T, U>>\n <U>(_: U): TypeAssertionResult<MutuallyAssignable<T, U>>\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import type { Extends, If } from '../../../utils/index.js';
2
+ import type { TypeAssertionResult } from '../index.js';
3
+ export type Extend<T> = {
4
+ /**
5
+ * Tests if the current type T extends the provided type U.
6
+ *
7
+ * @template U The type to check extension against
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { expect } from '@leawind/lay-sing'
12
+ *
13
+ * expect<3.14>().to.extend<number>().pass
14
+ * expect<2>().to.extend<string>().fail
15
+ * expect<'hello'>().to.extend<string>().pass
16
+ * ```
17
+ */
18
+ <U>(): TypeAssertionResult<Extends<T, U>>;
19
+ <U>(_: U): TypeAssertionResult<Extends<T, U>>;
20
+ } & If<Extends<T, number>, {
21
+ number: void;
22
+ }, {}> & If<Extends<T, bigint>, {
23
+ bigint: void;
24
+ }, {}> & If<Extends<T, string>, {
25
+ string: void;
26
+ }, {}> & If<Extends<T, boolean>, {
27
+ boolean: void;
28
+ }, {}> & If<Extends<T, symbol>, {
29
+ symbol: void;
30
+ }, {}>;
31
+ //# sourceMappingURL=extend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../../../src/main/expect/to/extend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,MAAM,MAAM,CAAC,CAAC,IAChB;IACA;;;;;;;;;;;;;OAaG;IACH,CAAC,CAAC,KAAK,mBAAmB,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACzC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CAC9C,GACC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GAC5C,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GAC5C,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GAC5C,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,GAC9C,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,EAAE,EAAE,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=extend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend.js","sourceRoot":"","sources":["../../../../src/main/expect/to/extend.ts"],"names":[],"mappings":"","sourcesContent":["import type { Extends, If } from '../../../utils/index.js'\nimport type { TypeAssertionResult } from '../index.js'\n\nexport type Extend<T> =\n & {\n /**\n * Tests if the current type T extends the provided type U.\n *\n * @template U The type to check extension against\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<3.14>().to.extend<number>().pass\n * expect<2>().to.extend<string>().fail\n * expect<'hello'>().to.extend<string>().pass\n * ```\n */\n <U>(): TypeAssertionResult<Extends<T, U>>\n <U>(_: U): TypeAssertionResult<Extends<T, U>>\n }\n & If<Extends<T, number>, { number: void }, {}>\n & If<Extends<T, bigint>, { bigint: void }, {}>\n & If<Extends<T, string>, { string: void }, {}>\n & If<Extends<T, boolean>, { boolean: void }, {}>\n & If<Extends<T, symbol>, { symbol: void }, {}>\n"]}
@@ -0,0 +1,38 @@
1
+ import type { Extends, IfTupleIncludes } from '../../../utils/index.js';
2
+ import type { TypeAssertionResult } from '../index.js';
3
+ type Result<T, K extends PropertyKey> = IfTupleIncludes<[
4
+ never,
5
+ any
6
+ ], K, never, TypeAssertionResult<Extends<K, keyof T>>>;
7
+ export type HaveKey<T> = {
8
+ /**
9
+ * Tests if the current type `T` has a property with key `K`.
10
+ *
11
+ * @template K The property key to check for
12
+ *
13
+ * ### Behavior
14
+ *
15
+ * - For single keys: succeeds if the key exists in `T`
16
+ * - For union types: succeeds only if **all** keys in the union exist in `T`
17
+ *
18
+ * ### Examples
19
+ *
20
+ * ```ts
21
+ * import { expect } from '@leawind/lay-sing'
22
+ *
23
+ * type WithProp = { prop: string; another: number; may?: 5 }
24
+ *
25
+ * // Single key checks
26
+ * expect<WithProp>().to.haveKey<'prop'>().pass
27
+ * expect<WithProp>().to.haveKey<'missing'>().fail
28
+ *
29
+ * // Union type checks
30
+ * expect<WithProp>().to.haveKey<'prop' | 'another'>().pass
31
+ * expect<WithProp>().to.haveKey<'may' | 'unexist'>().fail
32
+ * ```
33
+ */
34
+ <K extends PropertyKey>(): Result<T, K>;
35
+ <K extends PropertyKey>(_: K): Result<T, K>;
36
+ };
37
+ export {};
38
+ //# sourceMappingURL=have-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"have-key.d.ts","sourceRoot":"","sources":["../../../../src/main/expect/to/have-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,eAAe,CACrD;IAAC,KAAK;IAAE,GAAG;CAAC,EACZ,CAAC,EACD,KAAK,EACL,mBAAmB,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CACzC,CAAA;AAED,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,CAAC,CAAC,SAAS,WAAW,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CAC5C,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=have-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"have-key.js","sourceRoot":"","sources":["../../../../src/main/expect/to/have-key.ts"],"names":[],"mappings":"","sourcesContent":["import type { Extends, IfTupleIncludes } from '../../../utils/index.js'\nimport type { TypeAssertionResult } from '../index.js'\n\ntype Result<T, K extends PropertyKey> = IfTupleIncludes<\n [never, any],\n K,\n never,\n TypeAssertionResult<Extends<K, keyof T>>\n>\n\nexport type HaveKey<T> = {\n /**\n * Tests if the current type `T` has a property with key `K`.\n *\n * @template K The property key to check for\n *\n * ### Behavior\n *\n * - For single keys: succeeds if the key exists in `T`\n * - For union types: succeeds only if **all** keys in the union exist in `T`\n *\n * ### Examples\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * type WithProp = { prop: string; another: number; may?: 5 }\n *\n * // Single key checks\n * expect<WithProp>().to.haveKey<'prop'>().pass\n * expect<WithProp>().to.haveKey<'missing'>().fail\n *\n * // Union type checks\n * expect<WithProp>().to.haveKey<'prop' | 'another'>().pass\n * expect<WithProp>().to.haveKey<'may' | 'unexist'>().fail\n * ```\n */\n <K extends PropertyKey>(): Result<T, K>\n <K extends PropertyKey>(_: K): Result<T, K>\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { Be } from './be.js';
2
+ import type { Equal } from './equal.js';
3
+ import type { Extend } from './extend.js';
4
+ import type { ProperExtends } from './proper-extends.js';
5
+ import type { HaveKey } from './have-key.js';
6
+ export type To<T> = {
7
+ be: Be<T>;
8
+ equal: Equal<T>;
9
+ extend: Extend<T>;
10
+ properExtend: ProperExtends<T>;
11
+ haveKey: HaveKey<T>;
12
+ };
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/main/expect/to/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE5C,MAAM,MAAM,EAAE,CAAC,CAAC,IAAI;IAClB,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACT,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACf,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IACjB,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CACpB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/main/expect/to/index.ts"],"names":[],"mappings":"","sourcesContent":["import type { Be } from './be.js'\nimport type { Equal } from './equal.js'\nimport type { Extend } from './extend.js'\nimport type { ProperExtends } from './proper-extends.js'\nimport type { HaveKey } from './have-key.js'\n\nexport type To<T> = {\n be: Be<T>\n equal: Equal<T>\n extend: Extend<T>\n properExtend: ProperExtends<T>\n haveKey: HaveKey<T>\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import type { ProperExtend } from '../../../utils/index.js';
2
+ import type { TypeAssertionResult } from '../index.js';
3
+ export type ProperExtends<T> = {
4
+ /**
5
+ * Tests if the current type T properly extends the provided type U (extends but is not the same).
6
+ *
7
+ * @template U The type to check proper extension against
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { expect } from '@leawind/lay-sing'
12
+ *
13
+ * expect<2>().to.properExtend<number>().pass
14
+ * expect<'a' | 'b'>().to.properExtend<string>().pass
15
+ * expect<number>().to.properExtend<number>().fail
16
+ * ```
17
+ */
18
+ <U>(): TypeAssertionResult<ProperExtend<T, U>>;
19
+ <U>(_: U): TypeAssertionResult<ProperExtend<T, U>>;
20
+ };
21
+ //# sourceMappingURL=proper-extends.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proper-extends.d.ts","sourceRoot":"","sources":["../../../../src/main/expect/to/proper-extends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B;;;;;;;;;;;;;OAaG;IACH,CAAC,CAAC,KAAK,mBAAmB,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CACnD,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=proper-extends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proper-extends.js","sourceRoot":"","sources":["../../../../src/main/expect/to/proper-extends.ts"],"names":[],"mappings":"","sourcesContent":["import type { ProperExtend } from '../../../utils/index.js'\nimport type { TypeAssertionResult } from '../index.js'\n\nexport type ProperExtends<T> = {\n /**\n * Tests if the current type T properly extends the provided type U (extends but is not the same).\n *\n * @template U The type to check proper extension against\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<2>().to.properExtend<number>().pass\n * expect<'a' | 'b'>().to.properExtend<string>().pass\n * expect<number>().to.properExtend<number>().fail\n * ```\n */\n <U>(): TypeAssertionResult<ProperExtend<T, U>>\n <U>(_: U): TypeAssertionResult<ProperExtend<T, U>>\n}\n"]}
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import type { ExpectType } from './expect.js';
7
- export type { ExpectType } from './expect.js';
6
+ import type { ExpectType } from './expect/index.js';
7
+ export type { ExpectType } from './expect/index.js';
8
8
  export { NOOP } from './noop.js';
9
9
  /**
10
10
  * Creates an instance of ExpectType to perform type-level assertions on the given type.
@@ -18,13 +18,15 @@ export { NOOP } from './noop.js';
18
18
  * @example
19
19
  * ```ts
20
20
  * // Test exact type equality
21
- * expect<number>().toBe<number>().success
22
- * expect<number>().toBe<string>().fail
21
+ * expect<number>().to.be<number>().pass
22
+ * expect<number>().to.be<string>().fail
23
23
  * // Test if one type extends another
24
- * expect<3.14>().toExtend<number>().success
25
- * expect<2>().toExtend<string>().fail
24
+ * expect<3.14>().to.extend<number>().pass
25
+ * expect<2>().to.extend<string>().fail
26
26
  * ```
27
27
  */
28
- export declare function expect<T>(): ExpectType<T>;
29
- export declare function expect<T>(_: T): ExpectType<T>;
28
+ export declare const expect: {
29
+ <T>(): ExpectType<T>;
30
+ <T>(_: T): ExpectType<T>;
31
+ };
30
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAA;AAC1C,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,MAAM,EAAE;IACnB,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAA;IACpB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;CAClB,CAAA"}
package/esm/main/index.js CHANGED
@@ -5,7 +5,24 @@
5
5
  */
6
6
  import { NOOP } from './noop.js';
7
7
  export { NOOP } from './noop.js';
8
- export function expect() {
9
- return NOOP;
10
- }
8
+ /**
9
+ * Creates an instance of ExpectType to perform type-level assertions on the given type.
10
+ * This function enables testing various type relationships at compile time.
11
+ * NOTE: This function does nothing at runtime and is purely for type-level testing.
12
+ *
13
+ * @template T The type to be tested
14
+ *
15
+ * @returns An ExpectType instance with methods to test type relationships
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * // Test exact type equality
20
+ * expect<number>().to.be<number>().pass
21
+ * expect<number>().to.be<string>().fail
22
+ * // Test if one type extends another
23
+ * expect<3.14>().to.extend<number>().pass
24
+ * expect<2>().to.extend<string>().fail
25
+ * ```
26
+ */
27
+ export const expect = NOOP;
11
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAuBhC,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["/**\n * [Full API documentation is available on JSR](https://jsr.io/@leawind/lay-sing/doc)\n *\n * @module\n */\n\nimport type { ExpectType } from './expect.js'\nimport { NOOP } from './noop.js'\n\nexport type { ExpectType } from './expect.js'\nexport { NOOP } from './noop.js'\n\n/**\n * Creates an instance of ExpectType to perform type-level assertions on the given type.\n * This function enables testing various type relationships at compile time.\n * NOTE: This function does nothing at runtime and is purely for type-level testing.\n *\n * @template T The type to be tested\n *\n * @returns An ExpectType instance with methods to test type relationships\n *\n * @example\n * ```ts\n * // Test exact type equality\n * expect<number>().toBe<number>().success\n * expect<number>().toBe<string>().fail\n * // Test if one type extends another\n * expect<3.14>().toExtend<number>().success\n * expect<2>().toExtend<string>().fail\n * ```\n */\nexport function expect<T>(): ExpectType<T>\nexport function expect<T>(_: T): ExpectType<T>\nexport function expect<T>(): ExpectType<T> {\n return NOOP\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,MAAM,GAGf,IAAI,CAAA","sourcesContent":["/**\n * [Full API documentation is available on JSR](https://jsr.io/@leawind/lay-sing/doc)\n *\n * @module\n */\n\nimport type { ExpectType } from './expect/index.js'\nimport { NOOP } from './noop.js'\n\nexport type { ExpectType } from './expect/index.js'\nexport { NOOP } from './noop.js'\n\n/**\n * Creates an instance of ExpectType to perform type-level assertions on the given type.\n * This function enables testing various type relationships at compile time.\n * NOTE: This function does nothing at runtime and is purely for type-level testing.\n *\n * @template T The type to be tested\n *\n * @returns An ExpectType instance with methods to test type relationships\n *\n * @example\n * ```ts\n * // Test exact type equality\n * expect<number>().to.be<number>().pass\n * expect<number>().to.be<string>().fail\n * // Test if one type extends another\n * expect<3.14>().to.extend<number>().pass\n * expect<2>().to.extend<string>().fail\n * ```\n */\nexport const expect: {\n <T>(): ExpectType<T>\n <T>(_: T): ExpectType<T>\n} = NOOP\n"]}
@@ -17,14 +17,14 @@
17
17
  * ```ts
18
18
  * import { expect } from '@leawind/lay-sing'
19
19
  *
20
- * expect<Exact<string, string>>().toBeTrue
21
- * expect<Exact<never, never>>().toBeTrue
22
- * expect<Exact<any, any>>().toBeTrue
23
- *
24
- * expect<Exact<{ a: 3 }, { a?: 3 }>>().toBeFalse
25
- * expect<Exact<1 | 2, 1>>().toBeFalse
26
- * expect<Exact<1, number>>().toBeFalse
27
- * expect<Exact<() => void, () => undefined>>().toBeFalse
20
+ * expect<Exact<string, string>>().to.be.true
21
+ * expect<Exact<never, never>>().to.be.true
22
+ * expect<Exact<any, any>>().to.be.true
23
+ *
24
+ * expect<Exact<{ a: 3 }, { a?: 3 }>>().to.be.false
25
+ * expect<Exact<1 | 2, 1>>().to.be.false
26
+ * expect<Exact<1, number>>().to.be.false
27
+ * expect<Exact<() => void, () => undefined>>().to.be.false
28
28
  * ```
29
29
  */
30
30
  export type Exact<A, B, Yes = true, No = false> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Yes : No;
@@ -1 +1 @@
1
- {"version":3,"file":"exact.js","sourceRoot":"","sources":["../../../src/utils/compare/exact.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Checks whether two types are exactly the same.\n *\n * **⚠️Important:** parameter `A` and `B` are not distributive. When they are union type, it does not check each member separately.\n *\n * @template A - The first type to compare\n * @template B - The second type to compare\n * @template Yes - The result if types are exactly the same (defaults to `true`)\n * @template No - The result if types are not exactly the same (defaults to `false`)\n *\n * ### Result\n *\n * - `Yes`: `A` and `B` are exactly the same\n * - `No`: Otherwise\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<Exact<string, string>>().toBeTrue\n * expect<Exact<never, never>>().toBeTrue\n * expect<Exact<any, any>>().toBeTrue\n *\n * expect<Exact<{ a: 3 }, { a?: 3 }>>().toBeFalse\n * expect<Exact<1 | 2, 1>>().toBeFalse\n * expect<Exact<1, number>>().toBeFalse\n * expect<Exact<() => void, () => undefined>>().toBeFalse\n * ```\n */\nexport type Exact<\n A,\n B,\n Yes = true,\n No = false,\n> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Yes : No\n\n/**\n * Checks whether two types are not exactly the same.\n *\n * This is the logical negation of `Exact<A, B>`.\n *\n * @template A - The first type to compare\n * @template B - The second type to compare\n * @template Yes - The result if types are not exactly the same (defaults to `true`)\n * @template No - The result if types are exactly the same (defaults to `false`)\n *\n * @example\n * ```ts\n * type T1 = NotExact<number, string> // true\n * type T2 = NotExact<1, number> // true\n * type F1 = NotExact<number, number> // false\n * type F2 = NotExact<1, 1> // false\n * ```\n */\nexport type NotExact<\n A,\n B,\n Yes = true,\n No = false,\n> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? No : Yes\n"]}
1
+ {"version":3,"file":"exact.js","sourceRoot":"","sources":["../../../src/utils/compare/exact.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Checks whether two types are exactly the same.\n *\n * **⚠️Important:** parameter `A` and `B` are not distributive. When they are union type, it does not check each member separately.\n *\n * @template A - The first type to compare\n * @template B - The second type to compare\n * @template Yes - The result if types are exactly the same (defaults to `true`)\n * @template No - The result if types are not exactly the same (defaults to `false`)\n *\n * ### Result\n *\n * - `Yes`: `A` and `B` are exactly the same\n * - `No`: Otherwise\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<Exact<string, string>>().to.be.true\n * expect<Exact<never, never>>().to.be.true\n * expect<Exact<any, any>>().to.be.true\n *\n * expect<Exact<{ a: 3 }, { a?: 3 }>>().to.be.false\n * expect<Exact<1 | 2, 1>>().to.be.false\n * expect<Exact<1, number>>().to.be.false\n * expect<Exact<() => void, () => undefined>>().to.be.false\n * ```\n */\nexport type Exact<\n A,\n B,\n Yes = true,\n No = false,\n> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Yes : No\n\n/**\n * Checks whether two types are not exactly the same.\n *\n * This is the logical negation of `Exact<A, B>`.\n *\n * @template A - The first type to compare\n * @template B - The second type to compare\n * @template Yes - The result if types are not exactly the same (defaults to `true`)\n * @template No - The result if types are exactly the same (defaults to `false`)\n *\n * @example\n * ```ts\n * type T1 = NotExact<number, string> // true\n * type T2 = NotExact<1, number> // true\n * type F1 = NotExact<number, number> // false\n * type F2 = NotExact<1, 1> // false\n * ```\n */\nexport type NotExact<\n A,\n B,\n Yes = true,\n No = false,\n> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? No : Yes\n"]}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  export * from './compare/index.js';
7
7
  export * from './logic/index.js';
8
+ export * from './misc.js';
8
9
  export * from './object/index.js';
9
10
  export * from './tuple/index.js';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,WAAW,CAAA;AACzB,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA"}
@@ -6,6 +6,7 @@
6
6
  // Index start >>>>>>>>>>>>>>>>
7
7
  export * from './compare/index.js';
8
8
  export * from './logic/index.js';
9
+ export * from './misc.js';
9
10
  export * from './object/index.js';
10
11
  export * from './tuple/index.js';
11
12
  // <<<<<<<<<<<<<<<< Index end
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+BAA+B;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,+BAA+B","sourcesContent":["/**\n * [Full API documentation is available on JSR](https://jsr.io/@leawind/lay-sing/doc)\n *\n * @module\n */\n\n// Index start >>>>>>>>>>>>>>>>\nexport * from './compare/index.js'\nexport * from './logic/index.js'\nexport * from './object/index.js'\nexport * from './tuple/index.js'\n// <<<<<<<<<<<<<<<< Index end\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+BAA+B;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,WAAW,CAAA;AACzB,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,+BAA+B","sourcesContent":["/**\n * [Full API documentation is available on JSR](https://jsr.io/@leawind/lay-sing/doc)\n *\n * @module\n */\n\n// Index start >>>>>>>>>>>>>>>>\nexport * from './compare/index.js'\nexport * from './logic/index.js'\nexport * from './misc.js'\nexport * from './object/index.js'\nexport * from './tuple/index.js'\n// <<<<<<<<<<<<<<<< Index end\n"]}
@@ -9,9 +9,9 @@
9
9
  * ```ts
10
10
  * import { expect } from '@leawind/lay-sing'
11
11
  *
12
- * expect<AssertExtends<string, number>>().toBeNever
13
- * expect<AssertExtends<1 | 2, 1>>().toBeNever
14
- * expect<AssertExtends<1, 1 | 2>>().toBe<1>().success
12
+ * expect<AssertExtends<string, number>>().to.be.never
13
+ * expect<AssertExtends<1 | 2, 1>>().to.be.never
14
+ * expect<AssertExtends<1, 1 | 2>>().to.be<1>().pass
15
15
  * ```
16
16
  */
17
17
  export type AssertExtends<T, U> = [T] extends [U] ? T : never;
@@ -1 +1 @@
1
- {"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../src/utils/logic/assert.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * **⚠️Important:** parameter `T` and `U` are not distributive. When they are union type, it treats them as a single entity.\n *\n * @template T - The type to test (not distributed over unions)\n * @template U - The constraint type to test against\n *\n * @example\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<AssertExtends<string, number>>().toBeNever\n * expect<AssertExtends<1 | 2, 1>>().toBeNever\n * expect<AssertExtends<1, 1 | 2>>().toBe<1>().success\n * ```\n */\nexport type AssertExtends<T, U> = [T] extends [U] ? T : never\n"]}
1
+ {"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../src/utils/logic/assert.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * **⚠️Important:** parameter `T` and `U` are not distributive. When they are union type, it treats them as a single entity.\n *\n * @template T - The type to test (not distributed over unions)\n * @template U - The constraint type to test against\n *\n * @example\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<AssertExtends<string, number>>().to.be.never\n * expect<AssertExtends<1 | 2, 1>>().to.be.never\n * expect<AssertExtends<1, 1 | 2>>().to.be<1>().pass\n * ```\n */\nexport type AssertExtends<T, U> = [T] extends [U] ? T : never\n"]}
@@ -80,7 +80,7 @@ export type SwitchExact<T, Cases extends readonly [unknown, unknown][], Default
80
80
  * [number, boolean],
81
81
  * [string, boolean],
82
82
  * ], Error>
83
- * >().toBe<boolean>().success
83
+ * >().to.be<boolean>().pass
84
84
  * ```
85
85
  */
86
86
  export type SwitchExtends<T, Cases extends readonly [unknown, unknown][], Default = never> = Cases extends [infer First, ...infer Rest] ? (First extends [infer C, infer R] ? ([T] extends [C] ? R : SwitchExtends<T, Rest extends readonly [unknown, unknown][] ? Rest : never, Default>) : never) : Default;
@@ -1 +1 @@
1
- {"version":3,"file":"switch.js","sourceRoot":"","sources":["../../../src/utils/logic/switch.ts"],"names":[],"mappings":"","sourcesContent":["import type { Exact } from '../index.js'\n\n/**\n * Case tuple type used with `SwitchExact` and `SwitchExtends`\n *\n * @template T - The condition type to match against\n * @template Result - The result type to return if match is found\n *\n * @example\n * ```ts\n * type MyCase = Case<1, 'one'>\n * // Equivalent to: [1, 'one']\n * ```\n *\n * @example\n * ```ts\n * import { SwitchExact, DefaultCase } from '@leawind/lay-sing/utils'\n * type NameMap<id> = SwitchExact<id, [\n * [1, 'Alice'],\n * [2, 'Bob'],\n * ], DefaultCase<'Steve'>>\n * ```\n *\n * @see SwitchExact\n */\nexport type Case<T = unknown, Result = unknown> = [T, Result]\n\n/**\n * Default case type used with `SwitchExact` and `SwitchExtends`\n *\n * @template T - The default result type\n *\n * @example\n * ```ts\n * import { SwitchExact, DefaultCase } from '@leawind/lay-sing/utils'\n * type NameMap<id> = SwitchExact<id, [\n * [1, 'Alice'],\n * [2, 'Bob'],\n * ], DefaultCase<'Steve'>>\n * ```\n *\n * @see SwitchExact\n */\nexport type DefaultCase<T> = T\n\n/**\n * Switch type that uses exact matching logic\n *\n * **⚠️Important:** `T` parameter is not distributive. When `T` is a union type, it does not check each member separately.\n *\n * @template T - The type to match against cases\n * @template Cases - Array of case tuples, each tuple has the form [Condition, Result]\n * @template Default - Default result if no exact match is found (defaults to `never`)\n *\n * @example\n * ```ts\n * import { SwitchExact, DefaultCase } from '@leawind/lay-sing/utils'\n * type Result = SwitchExact<2, [\n * [1, 'Alice'],\n * [2, 'Bob'],\n * [3, 'Charlie'],\n * ], DefaultCase<'Steve'>>\n *\n * // Result: 'Bob'\n * ```\n */\nexport type SwitchExact<\n T,\n Cases extends readonly [unknown, unknown][],\n Default = never,\n> = Cases extends [infer First, ...infer Rest] ? (\n First extends [infer Condition, infer Result] ? (Exact<T, Condition> extends true ? Result\n : (SwitchExact<T, Rest extends readonly [unknown, unknown][] ? Rest : never, Default>))\n : (never)\n )\n : Default\n\n/**\n * Switch type that uses 'extends' logic instead of 'Exact' logic\n *\n * **⚠️Important:** `T` parameter is not distributive. When `T` is a union type, it does not check each member separately.\n *\n * @template T - The type to match against cases\n * @template Cases - Array of case tuples, each tuple has the form [Condition, Result]\n * @template Default - Default result if no match is found (defaults to `never`)\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<\n * SwitchExtends<string, [\n * [number, boolean],\n * [string, boolean],\n * ], Error>\n * >().toBe<boolean>().success\n * ```\n */\nexport type SwitchExtends<\n T,\n Cases extends readonly [unknown, unknown][],\n Default = never,\n> = Cases extends [infer First, ...infer Rest] ? (\n First extends [infer C, infer R]\n ? ([T] extends [C] ? R : SwitchExtends<T, Rest extends readonly [unknown, unknown][] ? Rest : never, Default>)\n : never\n )\n : Default\n"]}
1
+ {"version":3,"file":"switch.js","sourceRoot":"","sources":["../../../src/utils/logic/switch.ts"],"names":[],"mappings":"","sourcesContent":["import type { Exact } from '../index.js'\n\n/**\n * Case tuple type used with `SwitchExact` and `SwitchExtends`\n *\n * @template T - The condition type to match against\n * @template Result - The result type to return if match is found\n *\n * @example\n * ```ts\n * type MyCase = Case<1, 'one'>\n * // Equivalent to: [1, 'one']\n * ```\n *\n * @example\n * ```ts\n * import { SwitchExact, DefaultCase } from '@leawind/lay-sing/utils'\n * type NameMap<id> = SwitchExact<id, [\n * [1, 'Alice'],\n * [2, 'Bob'],\n * ], DefaultCase<'Steve'>>\n * ```\n *\n * @see SwitchExact\n */\nexport type Case<T = unknown, Result = unknown> = [T, Result]\n\n/**\n * Default case type used with `SwitchExact` and `SwitchExtends`\n *\n * @template T - The default result type\n *\n * @example\n * ```ts\n * import { SwitchExact, DefaultCase } from '@leawind/lay-sing/utils'\n * type NameMap<id> = SwitchExact<id, [\n * [1, 'Alice'],\n * [2, 'Bob'],\n * ], DefaultCase<'Steve'>>\n * ```\n *\n * @see SwitchExact\n */\nexport type DefaultCase<T> = T\n\n/**\n * Switch type that uses exact matching logic\n *\n * **⚠️Important:** `T` parameter is not distributive. When `T` is a union type, it does not check each member separately.\n *\n * @template T - The type to match against cases\n * @template Cases - Array of case tuples, each tuple has the form [Condition, Result]\n * @template Default - Default result if no exact match is found (defaults to `never`)\n *\n * @example\n * ```ts\n * import { SwitchExact, DefaultCase } from '@leawind/lay-sing/utils'\n * type Result = SwitchExact<2, [\n * [1, 'Alice'],\n * [2, 'Bob'],\n * [3, 'Charlie'],\n * ], DefaultCase<'Steve'>>\n *\n * // Result: 'Bob'\n * ```\n */\nexport type SwitchExact<\n T,\n Cases extends readonly [unknown, unknown][],\n Default = never,\n> = Cases extends [infer First, ...infer Rest] ? (\n First extends [infer Condition, infer Result] ? (Exact<T, Condition> extends true ? Result\n : (SwitchExact<T, Rest extends readonly [unknown, unknown][] ? Rest : never, Default>))\n : (never)\n )\n : Default\n\n/**\n * Switch type that uses 'extends' logic instead of 'Exact' logic\n *\n * **⚠️Important:** `T` parameter is not distributive. When `T` is a union type, it does not check each member separately.\n *\n * @template T - The type to match against cases\n * @template Cases - Array of case tuples, each tuple has the form [Condition, Result]\n * @template Default - Default result if no match is found (defaults to `never`)\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<\n * SwitchExtends<string, [\n * [number, boolean],\n * [string, boolean],\n * ], Error>\n * >().to.be<boolean>().pass\n * ```\n */\nexport type SwitchExtends<\n T,\n Cases extends readonly [unknown, unknown][],\n Default = never,\n> = Cases extends [infer First, ...infer Rest] ? (\n First extends [infer C, infer R]\n ? ([T] extends [C] ? R : SwitchExtends<T, Rest extends readonly [unknown, unknown][] ? Rest : never, Default>)\n : never\n )\n : Default\n"]}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Creates an intersection of all types in the provided tuple
3
+ *
4
+ * ## `IntersectionOf<[A, B, ... T]>` = `A & B & ... & T`
5
+ *
6
+ * @template Types - A tuple of types to create an intersection from
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { expect } from '@leawind/lay-sing'
11
+ *
12
+ * type Result = IntersectionOf<[{ a: string }, { b: number }, { c: boolean }]>
13
+ * expect<Result>().to.extend<{ a: string } & { b: number } & { c: boolean }>().pass
14
+ * expect<Result>().to.extend<{ a: string; b: number; c: boolean }>().pass
15
+ * ```
16
+ */
17
+ export type IntersectionOf<Types extends readonly unknown[]> = Types extends [infer First, ...infer Rest] ? First & IntersectionOf<Rest> : unknown;
18
+ /**
19
+ * Creates a union of all types in the provided tuple
20
+ *
21
+ * ## `UnionOf<[A, B, ... T]>` = `A | B | ... | T`
22
+ *
23
+ * @template Types - A tuple of types to create a union from
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { expect } from '@leawind/lay-sing'
28
+ *
29
+ * type Result = UnionOf<[string, number, boolean]>
30
+ * expect<Result>().to.be<string | number | boolean>().pass
31
+ * ```
32
+ */
33
+ export type UnionOf<Types extends readonly unknown[]> = Types extends [infer First, ...infer Rest] ? First | UnionOf<Rest> : never;
34
+ //# sourceMappingURL=misc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../src/utils/misc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,cAAc,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,IAAI,KAAK,SAAS,CAAC,MAAM,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,GACrG,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,GAC5B,OAAO,CAAA;AAEX;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,OAAO,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,IAAI,KAAK,SAAS,CAAC,MAAM,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,GAC9F,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,GACrB,KAAK,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=misc.js.map