lay-sing 0.2.1 → 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 (340) hide show
  1. package/README.md +31 -35
  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 +26 -11
  31. package/esm/main/index.d.ts.map +1 -1
  32. package/esm/main/index.js +22 -13
  33. package/esm/main/index.js.map +1 -1
  34. package/esm/main/noop.d.ts +27 -0
  35. package/esm/main/noop.d.ts.map +1 -0
  36. package/esm/{test-utils/index.js → main/noop.js} +1 -12
  37. package/esm/main/noop.js.map +1 -0
  38. package/esm/utils/compare/assignable.d.ts +30 -0
  39. package/esm/utils/compare/assignable.d.ts.map +1 -0
  40. package/esm/utils/compare/assignable.js +2 -0
  41. package/esm/utils/compare/assignable.js.map +1 -0
  42. package/esm/utils/compare/exact.d.ts +50 -0
  43. package/esm/utils/compare/exact.d.ts.map +1 -0
  44. package/esm/utils/compare/exact.js +2 -0
  45. package/esm/utils/compare/exact.js.map +1 -0
  46. package/esm/utils/compare/extends.d.ts +46 -0
  47. package/esm/utils/compare/extends.d.ts.map +1 -0
  48. package/esm/utils/compare/extends.js +2 -0
  49. package/esm/utils/compare/extends.js.map +1 -0
  50. package/esm/utils/compare/index.d.ts +5 -0
  51. package/esm/utils/compare/index.d.ts.map +1 -0
  52. package/esm/utils/compare/index.js +7 -0
  53. package/esm/utils/compare/index.js.map +1 -0
  54. package/esm/utils/compare/overlap.d.ts +47 -0
  55. package/esm/utils/compare/overlap.d.ts.map +1 -0
  56. package/esm/utils/compare/overlap.js +2 -0
  57. package/esm/utils/compare/overlap.js.map +1 -0
  58. package/esm/utils/index.d.ts +11 -0
  59. package/esm/utils/index.d.ts.map +1 -0
  60. package/esm/utils/index.js +13 -0
  61. package/esm/utils/index.js.map +1 -0
  62. package/esm/utils/logic/assert.d.ts +18 -0
  63. package/esm/utils/logic/assert.d.ts.map +1 -0
  64. package/esm/utils/logic/assert.js +2 -0
  65. package/esm/utils/logic/assert.js.map +1 -0
  66. package/esm/utils/logic/if.d.ts +37 -0
  67. package/esm/utils/logic/if.d.ts.map +1 -0
  68. package/esm/utils/logic/if.js +2 -0
  69. package/esm/utils/logic/if.js.map +1 -0
  70. package/esm/utils/logic/index.d.ts +4 -0
  71. package/esm/utils/logic/index.d.ts.map +1 -0
  72. package/esm/utils/logic/index.js +6 -0
  73. package/esm/utils/logic/index.js.map +1 -0
  74. package/{script/main/control.d.ts → esm/utils/logic/switch.d.ts} +15 -40
  75. package/esm/utils/logic/switch.d.ts.map +1 -0
  76. package/esm/utils/logic/switch.js +2 -0
  77. package/esm/utils/logic/switch.js.map +1 -0
  78. package/esm/utils/misc.d.ts +34 -0
  79. package/esm/utils/misc.d.ts.map +1 -0
  80. package/esm/utils/misc.js +2 -0
  81. package/esm/utils/misc.js.map +1 -0
  82. package/esm/utils/object/index.d.ts +4 -0
  83. package/esm/utils/object/index.d.ts.map +1 -0
  84. package/esm/utils/object/index.js +6 -0
  85. package/esm/utils/object/index.js.map +1 -0
  86. package/{script/main/key.d.ts → esm/utils/object/keys.d.ts} +34 -34
  87. package/esm/utils/object/keys.d.ts.map +1 -0
  88. package/esm/utils/object/keys.js +2 -0
  89. package/esm/utils/object/keys.js.map +1 -0
  90. package/esm/utils/object/pick.d.ts +16 -0
  91. package/esm/utils/object/pick.d.ts.map +1 -0
  92. package/esm/utils/object/pick.js +2 -0
  93. package/esm/utils/object/pick.js.map +1 -0
  94. package/esm/utils/object/props.d.ts +17 -0
  95. package/esm/utils/object/props.d.ts.map +1 -0
  96. package/esm/utils/object/props.js +2 -0
  97. package/esm/utils/object/props.js.map +1 -0
  98. package/esm/utils/tuple/append.d.ts +17 -0
  99. package/esm/utils/tuple/append.d.ts.map +1 -0
  100. package/esm/utils/tuple/append.js +2 -0
  101. package/esm/utils/tuple/append.js.map +1 -0
  102. package/esm/utils/tuple/concat.d.ts +31 -0
  103. package/esm/utils/tuple/concat.d.ts.map +1 -0
  104. package/esm/utils/tuple/concat.js +2 -0
  105. package/esm/utils/tuple/concat.js.map +1 -0
  106. package/esm/utils/tuple/includes.d.ts +20 -0
  107. package/esm/utils/tuple/includes.d.ts.map +1 -0
  108. package/esm/utils/tuple/includes.js +2 -0
  109. package/esm/utils/tuple/includes.js.map +1 -0
  110. package/esm/utils/tuple/index.d.ts +4 -0
  111. package/esm/utils/tuple/index.d.ts.map +1 -0
  112. package/esm/utils/tuple/index.js +6 -0
  113. package/esm/utils/tuple/index.js.map +1 -0
  114. package/package.json +5 -5
  115. package/script/main/expect/index.d.ts +31 -0
  116. package/script/main/expect/index.d.ts.map +1 -0
  117. package/script/main/{async.js → expect/index.js} +1 -1
  118. package/script/main/expect/index.js.map +1 -0
  119. package/script/main/expect/to/be.d.ts +23 -0
  120. package/script/main/expect/to/be.d.ts.map +1 -0
  121. package/script/main/{type/set.js → expect/to/be.js} +1 -1
  122. package/script/main/expect/to/be.js.map +1 -0
  123. package/script/main/expect/to/equal.d.ts +26 -0
  124. package/script/main/expect/to/equal.d.ts.map +1 -0
  125. package/script/main/expect/to/equal.js +3 -0
  126. package/script/main/expect/to/equal.js.map +1 -0
  127. package/script/main/expect/to/extend.d.ts +31 -0
  128. package/script/main/expect/to/extend.d.ts.map +1 -0
  129. package/script/main/expect/to/extend.js +3 -0
  130. package/script/main/expect/to/extend.js.map +1 -0
  131. package/script/main/expect/to/have-key.d.ts +38 -0
  132. package/script/main/expect/to/have-key.d.ts.map +1 -0
  133. package/script/main/expect/to/have-key.js +3 -0
  134. package/script/main/expect/to/have-key.js.map +1 -0
  135. package/script/main/expect/to/index.d.ts +13 -0
  136. package/script/main/expect/to/index.d.ts.map +1 -0
  137. package/script/main/expect/to/index.js +3 -0
  138. package/script/main/expect/to/index.js.map +1 -0
  139. package/script/main/expect/to/proper-extends.d.ts +21 -0
  140. package/script/main/expect/to/proper-extends.d.ts.map +1 -0
  141. package/script/main/expect/to/proper-extends.js +3 -0
  142. package/script/main/expect/to/proper-extends.js.map +1 -0
  143. package/script/main/index.d.ts +26 -11
  144. package/script/main/index.d.ts.map +1 -1
  145. package/script/main/index.js +24 -27
  146. package/script/main/index.js.map +1 -1
  147. package/script/main/noop.d.ts +27 -0
  148. package/script/main/noop.d.ts.map +1 -0
  149. package/script/{test-utils/index.js → main/noop.js} +1 -14
  150. package/script/main/noop.js.map +1 -0
  151. package/script/utils/compare/assignable.d.ts +30 -0
  152. package/script/utils/compare/assignable.d.ts.map +1 -0
  153. package/script/utils/compare/assignable.js +3 -0
  154. package/script/utils/compare/assignable.js.map +1 -0
  155. package/script/utils/compare/exact.d.ts +50 -0
  156. package/script/utils/compare/exact.d.ts.map +1 -0
  157. package/script/utils/compare/exact.js +3 -0
  158. package/script/utils/compare/exact.js.map +1 -0
  159. package/script/utils/compare/extends.d.ts +46 -0
  160. package/script/utils/compare/extends.d.ts.map +1 -0
  161. package/script/{main/boolean.js → utils/compare/extends.js} +1 -1
  162. package/script/utils/compare/extends.js.map +1 -0
  163. package/script/utils/compare/index.d.ts +5 -0
  164. package/script/utils/compare/index.d.ts.map +1 -0
  165. package/script/utils/compare/index.js +23 -0
  166. package/script/utils/compare/index.js.map +1 -0
  167. package/script/utils/compare/overlap.d.ts +47 -0
  168. package/script/utils/compare/overlap.d.ts.map +1 -0
  169. package/script/{main/control.js → utils/compare/overlap.js} +1 -1
  170. package/script/utils/compare/overlap.js.map +1 -0
  171. package/script/utils/index.d.ts +11 -0
  172. package/script/utils/index.d.ts.map +1 -0
  173. package/script/utils/index.js +29 -0
  174. package/script/utils/index.js.map +1 -0
  175. package/script/utils/logic/assert.d.ts +18 -0
  176. package/script/utils/logic/assert.d.ts.map +1 -0
  177. package/script/utils/logic/assert.js +3 -0
  178. package/script/utils/logic/assert.js.map +1 -0
  179. package/script/utils/logic/if.d.ts +37 -0
  180. package/script/utils/logic/if.d.ts.map +1 -0
  181. package/script/{main/key.js → utils/logic/if.js} +1 -1
  182. package/script/utils/logic/if.js.map +1 -0
  183. package/script/utils/logic/index.d.ts +4 -0
  184. package/script/utils/logic/index.d.ts.map +1 -0
  185. package/script/utils/logic/index.js +22 -0
  186. package/script/utils/logic/index.js.map +1 -0
  187. package/{esm/main/control.d.ts → script/utils/logic/switch.d.ts} +15 -40
  188. package/script/utils/logic/switch.d.ts.map +1 -0
  189. package/script/utils/logic/switch.js +3 -0
  190. package/script/utils/logic/switch.js.map +1 -0
  191. package/script/utils/misc.d.ts +34 -0
  192. package/script/utils/misc.d.ts.map +1 -0
  193. package/script/{main/json.js → utils/misc.js} +1 -1
  194. package/script/utils/misc.js.map +1 -0
  195. package/script/utils/object/index.d.ts +4 -0
  196. package/script/utils/object/index.d.ts.map +1 -0
  197. package/script/{main/type → utils/object}/index.js +3 -2
  198. package/script/utils/object/index.js.map +1 -0
  199. package/{esm/main/key.d.ts → script/utils/object/keys.d.ts} +34 -34
  200. package/script/utils/object/keys.d.ts.map +1 -0
  201. package/script/{main/doc.js → utils/object/keys.js} +1 -1
  202. package/script/utils/object/keys.js.map +1 -0
  203. package/script/utils/object/pick.d.ts +16 -0
  204. package/script/utils/object/pick.d.ts.map +1 -0
  205. package/script/utils/object/pick.js +3 -0
  206. package/script/utils/object/pick.js.map +1 -0
  207. package/script/utils/object/props.d.ts +17 -0
  208. package/script/utils/object/props.d.ts.map +1 -0
  209. package/script/utils/object/props.js +3 -0
  210. package/script/utils/object/props.js.map +1 -0
  211. package/script/utils/tuple/append.d.ts +17 -0
  212. package/script/utils/tuple/append.d.ts.map +1 -0
  213. package/script/utils/tuple/append.js +3 -0
  214. package/script/utils/tuple/append.js.map +1 -0
  215. package/script/utils/tuple/concat.d.ts +31 -0
  216. package/script/utils/tuple/concat.d.ts.map +1 -0
  217. package/script/utils/tuple/concat.js +3 -0
  218. package/script/utils/tuple/concat.js.map +1 -0
  219. package/script/utils/tuple/includes.d.ts +20 -0
  220. package/script/utils/tuple/includes.d.ts.map +1 -0
  221. package/script/utils/tuple/includes.js +3 -0
  222. package/script/utils/tuple/includes.js.map +1 -0
  223. package/script/utils/tuple/index.d.ts +4 -0
  224. package/script/utils/tuple/index.d.ts.map +1 -0
  225. package/script/utils/tuple/index.js +22 -0
  226. package/script/utils/tuple/index.js.map +1 -0
  227. package/esm/main/async.d.ts +0 -13
  228. package/esm/main/async.d.ts.map +0 -1
  229. package/esm/main/async.js +0 -2
  230. package/esm/main/async.js.map +0 -1
  231. package/esm/main/boolean.d.ts +0 -59
  232. package/esm/main/boolean.d.ts.map +0 -1
  233. package/esm/main/boolean.js +0 -2
  234. package/esm/main/boolean.js.map +0 -1
  235. package/esm/main/control.d.ts.map +0 -1
  236. package/esm/main/control.js +0 -2
  237. package/esm/main/control.js.map +0 -1
  238. package/esm/main/doc.d.ts +0 -56
  239. package/esm/main/doc.d.ts.map +0 -1
  240. package/esm/main/doc.js +0 -2
  241. package/esm/main/doc.js.map +0 -1
  242. package/esm/main/function.d.ts +0 -27
  243. package/esm/main/function.d.ts.map +0 -1
  244. package/esm/main/function.js +0 -2
  245. package/esm/main/function.js.map +0 -1
  246. package/esm/main/json.d.ts +0 -44
  247. package/esm/main/json.d.ts.map +0 -1
  248. package/esm/main/json.js +0 -2
  249. package/esm/main/json.js.map +0 -1
  250. package/esm/main/key.d.ts.map +0 -1
  251. package/esm/main/key.js +0 -2
  252. package/esm/main/key.js.map +0 -1
  253. package/esm/main/object.d.ts +0 -120
  254. package/esm/main/object.d.ts.map +0 -1
  255. package/esm/main/object.js +0 -2
  256. package/esm/main/object.js.map +0 -1
  257. package/esm/main/tuple.d.ts +0 -64
  258. package/esm/main/tuple.d.ts.map +0 -1
  259. package/esm/main/tuple.js +0 -2
  260. package/esm/main/tuple.js.map +0 -1
  261. package/esm/main/type/compare.d.ts +0 -169
  262. package/esm/main/type/compare.d.ts.map +0 -1
  263. package/esm/main/type/compare.js +0 -2
  264. package/esm/main/type/compare.js.map +0 -1
  265. package/esm/main/type/index.d.ts +0 -3
  266. package/esm/main/type/index.d.ts.map +0 -1
  267. package/esm/main/type/index.js +0 -5
  268. package/esm/main/type/index.js.map +0 -1
  269. package/esm/main/type/set.d.ts +0 -34
  270. package/esm/main/type/set.d.ts.map +0 -1
  271. package/esm/main/type/set.js +0 -2
  272. package/esm/main/type/set.js.map +0 -1
  273. package/esm/main/typed-array.d.ts +0 -5
  274. package/esm/main/typed-array.d.ts.map +0 -1
  275. package/esm/main/typed-array.js +0 -2
  276. package/esm/main/typed-array.js.map +0 -1
  277. package/esm/test-utils/compare.d.ts +0 -81
  278. package/esm/test-utils/compare.d.ts.map +0 -1
  279. package/esm/test-utils/compare.js +0 -2
  280. package/esm/test-utils/compare.js.map +0 -1
  281. package/esm/test-utils/expect.d.ts +0 -278
  282. package/esm/test-utils/expect.d.ts.map +0 -1
  283. package/esm/test-utils/expect.js +0 -2
  284. package/esm/test-utils/expect.js.map +0 -1
  285. package/esm/test-utils/index.d.ts +0 -77
  286. package/esm/test-utils/index.d.ts.map +0 -1
  287. package/esm/test-utils/index.js.map +0 -1
  288. package/script/main/async.d.ts +0 -13
  289. package/script/main/async.d.ts.map +0 -1
  290. package/script/main/async.js.map +0 -1
  291. package/script/main/boolean.d.ts +0 -59
  292. package/script/main/boolean.d.ts.map +0 -1
  293. package/script/main/boolean.js.map +0 -1
  294. package/script/main/control.d.ts.map +0 -1
  295. package/script/main/control.js.map +0 -1
  296. package/script/main/doc.d.ts +0 -56
  297. package/script/main/doc.d.ts.map +0 -1
  298. package/script/main/doc.js.map +0 -1
  299. package/script/main/function.d.ts +0 -27
  300. package/script/main/function.d.ts.map +0 -1
  301. package/script/main/function.js +0 -3
  302. package/script/main/function.js.map +0 -1
  303. package/script/main/json.d.ts +0 -44
  304. package/script/main/json.d.ts.map +0 -1
  305. package/script/main/json.js.map +0 -1
  306. package/script/main/key.d.ts.map +0 -1
  307. package/script/main/key.js.map +0 -1
  308. package/script/main/object.d.ts +0 -120
  309. package/script/main/object.d.ts.map +0 -1
  310. package/script/main/object.js +0 -3
  311. package/script/main/object.js.map +0 -1
  312. package/script/main/tuple.d.ts +0 -64
  313. package/script/main/tuple.d.ts.map +0 -1
  314. package/script/main/tuple.js +0 -3
  315. package/script/main/tuple.js.map +0 -1
  316. package/script/main/type/compare.d.ts +0 -169
  317. package/script/main/type/compare.d.ts.map +0 -1
  318. package/script/main/type/compare.js +0 -3
  319. package/script/main/type/compare.js.map +0 -1
  320. package/script/main/type/index.d.ts +0 -3
  321. package/script/main/type/index.d.ts.map +0 -1
  322. package/script/main/type/index.js.map +0 -1
  323. package/script/main/type/set.d.ts +0 -34
  324. package/script/main/type/set.d.ts.map +0 -1
  325. package/script/main/type/set.js.map +0 -1
  326. package/script/main/typed-array.d.ts +0 -5
  327. package/script/main/typed-array.d.ts.map +0 -1
  328. package/script/main/typed-array.js +0 -3
  329. package/script/main/typed-array.js.map +0 -1
  330. package/script/test-utils/compare.d.ts +0 -81
  331. package/script/test-utils/compare.d.ts.map +0 -1
  332. package/script/test-utils/compare.js +0 -3
  333. package/script/test-utils/compare.js.map +0 -1
  334. package/script/test-utils/expect.d.ts +0 -278
  335. package/script/test-utils/expect.d.ts.map +0 -1
  336. package/script/test-utils/expect.js +0 -3
  337. package/script/test-utils/expect.js.map +0 -1
  338. package/script/test-utils/index.d.ts +0 -77
  339. package/script/test-utils/index.d.ts.map +0 -1
  340. package/script/test-utils/index.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
 
@@ -32,7 +32,7 @@ npm i -D lay-sing
32
32
  ```
33
33
 
34
34
  ```ts
35
- import { expect } from 'lay-sing/test-utils'
35
+ import { expect } from 'lay-sing'
36
36
  ```
37
37
 
38
38
  </details>
@@ -47,7 +47,7 @@ deno add npm:lay-sing
47
47
  ```
48
48
 
49
49
  ```ts
50
- import { expect } from 'lay-sing/test-utils'
50
+ import { expect } from 'lay-sing'
51
51
  ```
52
52
 
53
53
  ### From JSR
@@ -59,14 +59,14 @@ deno add @leawind/lay-sing
59
59
  ```
60
60
 
61
61
  ```ts
62
- import { expect } from '@leawind/lay-sing/test-utils'
62
+ import { expect } from '@leawind/lay-sing'
63
63
  ```
64
64
 
65
65
  ### From Latest commit
66
66
 
67
67
  ```ts
68
- import { expect } from 'https://raw.githubusercontent.com/Leawind/lay-sing/refs/heads/main/src/test-utils/index.ts'
69
- import { Exact } from 'https://raw.githubusercontent.com/Leawind/lay-sing/refs/heads/main/src/main/index.ts'
68
+ import { expect } from 'https://raw.githubusercontent.com/Leawind/lay-sing/refs/heads/main/src/main/index.ts'
69
+ import { Exact } from 'https://raw.githubusercontent.com/Leawind/lay-sing/refs/heads/main/src/utils/index.ts'
70
70
  ```
71
71
 
72
72
  </details>
@@ -75,22 +75,20 @@ import { Exact } from 'https://raw.githubusercontent.com/Leawind/lay-sing/refs/h
75
75
 
76
76
  ## Usage
77
77
 
78
- ### Testing Utilities
79
-
80
78
  ```ts
81
- import { expect } from 'lay-sing/test-utils'
79
+ import { expect } from 'lay-sing'
82
80
  ```
83
81
 
84
- The `test-utils` module provides utilities for **compile-time** type validation. These utilities have **no runtime impact** — they always return a special [`NOOP`](https://jsr.io/@leawind/lay-sing/doc/test-utils/~/NOOP) value that safely supports almost any property access or method call.
82
+ The main module provides utilities for **compile-time** type validation. These utilities have **no runtime impact** — they always return a special [`NOOP`](https://jsr.io/@leawind/lay-sing/doc/~/NOOP) value that safely supports almost any property access or method call.
85
83
 
86
84
  A typical type test statement follows this pattern:
87
85
 
88
86
  ```ts
89
- expect<ActualType>().toBe<ExpectedType>().success
87
+ expect<ActualType>().to.be<ExpectedType>().pass
90
88
  ```
91
89
 
92
90
  - It starts with a function call like `expect<T>()` or `compare<T, U>()`
93
- - It ends with a property like `.success` or `.fail`
91
+ - It ends with a property like `.pass` or `.fail`
94
92
  - Type error occurs only if the assertion fails
95
93
 
96
94
  > [!CAUTION]
@@ -98,8 +96,8 @@ expect<ActualType>().toBe<ExpectedType>().success
98
96
  > Only statements ending with property access are type assertions. Without property access, type error may never occur:
99
97
  >
100
98
  > ```diff
101
- > - expect<true>().toBe<false>() // Type error never occur
102
- > + 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; }'.
103
101
  > ```
104
102
 
105
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.
@@ -108,26 +106,26 @@ At runtime, the function always returns the `NOOP` object, which performs **no o
108
106
 
109
107
  ```ts
110
108
  // Passes only if A and B are identical
111
- expect<keyof { a: 2 }>().toBe<'a'>().success
109
+ expect<keyof { a: 2 }>().to.be<'a'>().pass
112
110
 
113
111
  // Passes if A extends B
114
- expect<12138>().toExtend<number>().success
112
+ expect<12138>().to.extend<number>().pass
115
113
 
116
114
  // Passes if mutually assignable
117
- expect<{ a: 1; b: 2 }>().toEqual<{ a: 1 } & { b: 2 }>().success
115
+ expect<{ a: 1; b: 2 }>().to.equal<{ a: 1 } & { b: 2 }>().pass
118
116
 
119
117
  // Test property existence
120
- expect<{ name: string }>().toHaveKey<'name'>().success
118
+ expect<{ name: string }>().to.haveKey<'name'>().pass
121
119
  ```
122
120
 
123
121
  Aliases:
124
122
 
125
123
  ```ts
126
- expect<never>().toBe<never>().success
127
- expect<never>().toBeNever
124
+ expect<never>().to.be<never>().pass
125
+ expect<never>().to.be.never
128
126
 
129
- expect<'hello'>().toExtend<string>().success
130
- expect<'hello'>().toExtendString
127
+ expect<'hello'>().to.extend<string>().pass
128
+ expect<'hello'>().to.extend.string
131
129
  ```
132
130
 
133
131
  #### NOOP
@@ -148,15 +146,18 @@ await NOOP // Does not await (not thenable)
148
146
 
149
147
  ### Type Tools
150
148
 
151
- The main entry point provides some utility types for common type-level programming tasks. All types are flat-exported from the main entry point — no need to import from nested paths.
149
+ It provides some utility types organized into categories for common type-level programming tasks. These can be imported from the `lay-sing/utils` entry point.
152
150
 
153
151
  ```ts
154
- import type { Exact } from 'lay-sing'
152
+ import type { Exact, Extends, Overlap } from 'lay-sing/utils'
155
153
  ```
156
154
 
157
155
  ### Examples
158
156
 
159
157
  ```typescript
158
+ // Import the utility types
159
+ import type { ConcatTuple, Exact, If, KeysOfBaseType } from '@leawind/lay-sing/utils'
160
+
160
161
  // Test if exactly the same
161
162
  type False = Exact<{ a: 1 }, { a?: 1 }> // false
162
163
  type Yes = Exact<boolean, true | false, 'yes', 'no'> // 'yes'
@@ -164,15 +165,10 @@ type Yes = Exact<boolean, true | false, 'yes', 'no'> // 'yes'
164
165
  // Conditional Types
165
166
  type Result = If<true, 'yes', 'no'> // 'yes'
166
167
 
167
- // Boolean Logic
168
- type IsTrue = And<true, true> // true
168
+ type FailResult = If<Exact<number, string>, 'yes', 'no'> // 'no'
169
169
 
170
170
  // Tuple Manipulation
171
171
  type Combined = ConcatTuple<[1, 2], [3, 4]> // [1, 2, 3, 4]
172
172
 
173
- // Object Utilities
174
- type PartialObj = DeepPartial<{ a: string; nested: { b: number } }>
175
- // { a?: string; nested?: { b?: number } }
173
+ type UniqueCombined = ConcatUniqueTuple<[1, 2], [2, 3]> // [1, 2, 3]
176
174
  ```
177
-
178
- [Full API documentation is available on JSR](https://jsr.io/@leawind/lay-sing/doc)
@@ -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,15 +3,30 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- export * from './async.js';
7
- export * from './boolean.js';
8
- export * from './control.js';
9
- export * from './doc.js';
10
- export * from './function.js';
11
- export * from './json.js';
12
- export * from './key.js';
13
- export * from './object.js';
14
- export * from './tuple.js';
15
- export * from './type/index.js';
16
- export * from './typed-array.js';
6
+ import type { ExpectType } from './expect/index.js';
7
+ export type { ExpectType } from './expect/index.js';
8
+ export { NOOP } from './noop.js';
9
+ /**
10
+ * Creates an instance of ExpectType to perform type-level assertions on the given type.
11
+ * This function enables testing various type relationships at compile time.
12
+ * NOTE: This function does nothing at runtime and is purely for type-level testing.
13
+ *
14
+ * @template T The type to be tested
15
+ *
16
+ * @returns An ExpectType instance with methods to test type relationships
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Test exact type equality
21
+ * expect<number>().to.be<number>().pass
22
+ * expect<number>().to.be<string>().fail
23
+ * // Test if one type extends another
24
+ * expect<3.14>().to.extend<number>().pass
25
+ * expect<2>().to.extend<string>().fail
26
+ * ```
27
+ */
28
+ export declare const expect: {
29
+ <T>(): ExpectType<T>;
30
+ <T>(_: T): ExpectType<T>;
31
+ };
17
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;AAGH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,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
@@ -3,17 +3,26 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- // Index start >>>>>>>>>>>>>>>>
7
- export * from './async.js';
8
- export * from './boolean.js';
9
- export * from './control.js';
10
- export * from './doc.js';
11
- export * from './function.js';
12
- export * from './json.js';
13
- export * from './key.js';
14
- export * from './object.js';
15
- export * from './tuple.js';
16
- export * from './type/index.js';
17
- export * from './typed-array.js';
18
- // <<<<<<<<<<<<<<<< Index end
6
+ import { NOOP } from './noop.js';
7
+ export { NOOP } from './noop.js';
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;
19
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+BAA+B;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,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 './async.js'\nexport * from './boolean.js'\nexport * from './control.js'\nexport * from './doc.js'\nexport * from './function.js'\nexport * from './json.js'\nexport * from './key.js'\nexport * from './object.js'\nexport * from './tuple.js'\nexport * from './type/index.js'\nexport * from './typed-array.js'\n// <<<<<<<<<<<<<<<< Index end\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"]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A universal no-op placeholder implemented via `Proxy`.
3
+ *
4
+ * `NOOP` can be accessed, called, or chained indefinitely without throwing.
5
+ * Every operation returns itself, making it safe to use as a dummy fallback
6
+ * for APIs, optional hooks, or unimplemented interfaces.
7
+ *
8
+ * ### Special behaviors
9
+ *
10
+ * - Callable: invoking `NOOP()` returns `NOOP`
11
+ * - Property access: `NOOP.anything` returns `NOOP`
12
+ * - Promise-safe: `NOOP.then` is `undefined`, so it is not treated as a Promise
13
+ * - Primitive coercion (`toString`, `valueOf`, `Symbol.toPrimitive`) yields
14
+ * a stable string representation: `"[NOOP]"`
15
+ *
16
+ * This is useful in scenarios where a value is required syntactically but
17
+ * should perform no action and never fail at runtime.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * NOOP.foo.bar().baz.qux; // safe, returns NOOP
22
+ * String(NOOP); // "[NOOP]"
23
+ * await NOOP; // does not await (not thenable)
24
+ * ```
25
+ */
26
+ export declare const NOOP: any;
27
+ //# sourceMappingURL=noop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noop.d.ts","sourceRoot":"","sources":["../../src/main/noop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,IAAI,EAAE,GA0BlB,CAAA"}
@@ -1,8 +1,3 @@
1
- /**
2
- * [Full API documentation is available on JSR](https://jsr.io/@leawind/lay-sing/doc)
3
- *
4
- * @module
5
- */
6
1
  /**
7
2
  * A universal no-op placeholder implemented via `Proxy`.
8
3
  *
@@ -52,10 +47,4 @@ export const NOOP = new Proxy(function () {
52
47
  has: () => true,
53
48
  ownKeys: () => ['prototype'],
54
49
  });
55
- export function compare() {
56
- return NOOP;
57
- }
58
- export function expect() {
59
- return NOOP;
60
- }
61
- //# sourceMappingURL=index.js.map
50
+ //# sourceMappingURL=noop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noop.js","sourceRoot":"","sources":["../../src/main/noop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAQ,IAAI,KAAK,CAChC;IACE,OAAO,IAAI,CAAA;AACb,CAAC,EACD;IACE,GAAG,CAAC,CAAC,EAAE,IAAI;QACT,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,MAAM;gBACT,OAAO,SAAS,CAAA;YAClB,KAAK,SAAS,CAAC;YACf,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC,WAAW;gBACrB,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAA;YACvB;gBACE,OAAO,IAAI,CAAA;QACf,CAAC;IACH,CAAC;IACD,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI;IACf,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/B,YAAY,EAAE,IAAI;QAClB,KAAK,EAAE,IAAI;KACZ,CAAC;IACF,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;IAC1B,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI;IACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC;CAC7B,CACF,CAAA","sourcesContent":["/**\n * A universal no-op placeholder implemented via `Proxy`.\n *\n * `NOOP` can be accessed, called, or chained indefinitely without throwing.\n * Every operation returns itself, making it safe to use as a dummy fallback\n * for APIs, optional hooks, or unimplemented interfaces.\n *\n * ### Special behaviors\n *\n * - Callable: invoking `NOOP()` returns `NOOP`\n * - Property access: `NOOP.anything` returns `NOOP`\n * - Promise-safe: `NOOP.then` is `undefined`, so it is not treated as a Promise\n * - Primitive coercion (`toString`, `valueOf`, `Symbol.toPrimitive`) yields\n * a stable string representation: `\"[NOOP]\"`\n *\n * This is useful in scenarios where a value is required syntactically but\n * should perform no action and never fail at runtime.\n *\n * @example\n * ```ts\n * NOOP.foo.bar().baz.qux; // safe, returns NOOP\n * String(NOOP); // \"[NOOP]\"\n * await NOOP; // does not await (not thenable)\n * ```\n */\nexport const NOOP: any = new Proxy(\n function () {\n return NOOP\n },\n {\n get(_, prop) {\n switch (prop) {\n case 'then':\n return undefined\n case 'valueOf':\n case 'toString':\n case Symbol.toPrimitive:\n return () => '[NOOP]'\n default:\n return NOOP\n }\n },\n set: () => true,\n getOwnPropertyDescriptor: () => ({\n configurable: true,\n value: NOOP,\n }),\n getPrototypeOf: () => null,\n has: () => true,\n ownKeys: () => ['prototype'],\n },\n)\n"]}