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.
- package/README.md +31 -35
- package/esm/main/expect/index.d.ts +31 -0
- package/esm/main/expect/index.d.ts.map +1 -0
- package/esm/main/expect/index.js +2 -0
- package/esm/main/expect/index.js.map +1 -0
- package/esm/main/expect/to/be.d.ts +23 -0
- package/esm/main/expect/to/be.d.ts.map +1 -0
- package/esm/main/expect/to/be.js +2 -0
- package/esm/main/expect/to/be.js.map +1 -0
- package/esm/main/expect/to/equal.d.ts +26 -0
- package/esm/main/expect/to/equal.d.ts.map +1 -0
- package/esm/main/expect/to/equal.js +2 -0
- package/esm/main/expect/to/equal.js.map +1 -0
- package/esm/main/expect/to/extend.d.ts +31 -0
- package/esm/main/expect/to/extend.d.ts.map +1 -0
- package/esm/main/expect/to/extend.js +2 -0
- package/esm/main/expect/to/extend.js.map +1 -0
- package/esm/main/expect/to/have-key.d.ts +38 -0
- package/esm/main/expect/to/have-key.d.ts.map +1 -0
- package/esm/main/expect/to/have-key.js +2 -0
- package/esm/main/expect/to/have-key.js.map +1 -0
- package/esm/main/expect/to/index.d.ts +13 -0
- package/esm/main/expect/to/index.d.ts.map +1 -0
- package/esm/main/expect/to/index.js +2 -0
- package/esm/main/expect/to/index.js.map +1 -0
- package/esm/main/expect/to/proper-extends.d.ts +21 -0
- package/esm/main/expect/to/proper-extends.d.ts.map +1 -0
- package/esm/main/expect/to/proper-extends.js +2 -0
- package/esm/main/expect/to/proper-extends.js.map +1 -0
- package/esm/main/index.d.ts +26 -11
- package/esm/main/index.d.ts.map +1 -1
- package/esm/main/index.js +22 -13
- package/esm/main/index.js.map +1 -1
- package/esm/main/noop.d.ts +27 -0
- package/esm/main/noop.d.ts.map +1 -0
- package/esm/{test-utils/index.js → main/noop.js} +1 -12
- package/esm/main/noop.js.map +1 -0
- package/esm/utils/compare/assignable.d.ts +30 -0
- package/esm/utils/compare/assignable.d.ts.map +1 -0
- package/esm/utils/compare/assignable.js +2 -0
- package/esm/utils/compare/assignable.js.map +1 -0
- package/esm/utils/compare/exact.d.ts +50 -0
- package/esm/utils/compare/exact.d.ts.map +1 -0
- package/esm/utils/compare/exact.js +2 -0
- package/esm/utils/compare/exact.js.map +1 -0
- package/esm/utils/compare/extends.d.ts +46 -0
- package/esm/utils/compare/extends.d.ts.map +1 -0
- package/esm/utils/compare/extends.js +2 -0
- package/esm/utils/compare/extends.js.map +1 -0
- package/esm/utils/compare/index.d.ts +5 -0
- package/esm/utils/compare/index.d.ts.map +1 -0
- package/esm/utils/compare/index.js +7 -0
- package/esm/utils/compare/index.js.map +1 -0
- package/esm/utils/compare/overlap.d.ts +47 -0
- package/esm/utils/compare/overlap.d.ts.map +1 -0
- package/esm/utils/compare/overlap.js +2 -0
- package/esm/utils/compare/overlap.js.map +1 -0
- package/esm/utils/index.d.ts +11 -0
- package/esm/utils/index.d.ts.map +1 -0
- package/esm/utils/index.js +13 -0
- package/esm/utils/index.js.map +1 -0
- package/esm/utils/logic/assert.d.ts +18 -0
- package/esm/utils/logic/assert.d.ts.map +1 -0
- package/esm/utils/logic/assert.js +2 -0
- package/esm/utils/logic/assert.js.map +1 -0
- package/esm/utils/logic/if.d.ts +37 -0
- package/esm/utils/logic/if.d.ts.map +1 -0
- package/esm/utils/logic/if.js +2 -0
- package/esm/utils/logic/if.js.map +1 -0
- package/esm/utils/logic/index.d.ts +4 -0
- package/esm/utils/logic/index.d.ts.map +1 -0
- package/esm/utils/logic/index.js +6 -0
- package/esm/utils/logic/index.js.map +1 -0
- package/{script/main/control.d.ts → esm/utils/logic/switch.d.ts} +15 -40
- package/esm/utils/logic/switch.d.ts.map +1 -0
- package/esm/utils/logic/switch.js +2 -0
- package/esm/utils/logic/switch.js.map +1 -0
- package/esm/utils/misc.d.ts +34 -0
- package/esm/utils/misc.d.ts.map +1 -0
- package/esm/utils/misc.js +2 -0
- package/esm/utils/misc.js.map +1 -0
- package/esm/utils/object/index.d.ts +4 -0
- package/esm/utils/object/index.d.ts.map +1 -0
- package/esm/utils/object/index.js +6 -0
- package/esm/utils/object/index.js.map +1 -0
- package/{script/main/key.d.ts → esm/utils/object/keys.d.ts} +34 -34
- package/esm/utils/object/keys.d.ts.map +1 -0
- package/esm/utils/object/keys.js +2 -0
- package/esm/utils/object/keys.js.map +1 -0
- package/esm/utils/object/pick.d.ts +16 -0
- package/esm/utils/object/pick.d.ts.map +1 -0
- package/esm/utils/object/pick.js +2 -0
- package/esm/utils/object/pick.js.map +1 -0
- package/esm/utils/object/props.d.ts +17 -0
- package/esm/utils/object/props.d.ts.map +1 -0
- package/esm/utils/object/props.js +2 -0
- package/esm/utils/object/props.js.map +1 -0
- package/esm/utils/tuple/append.d.ts +17 -0
- package/esm/utils/tuple/append.d.ts.map +1 -0
- package/esm/utils/tuple/append.js +2 -0
- package/esm/utils/tuple/append.js.map +1 -0
- package/esm/utils/tuple/concat.d.ts +31 -0
- package/esm/utils/tuple/concat.d.ts.map +1 -0
- package/esm/utils/tuple/concat.js +2 -0
- package/esm/utils/tuple/concat.js.map +1 -0
- package/esm/utils/tuple/includes.d.ts +20 -0
- package/esm/utils/tuple/includes.d.ts.map +1 -0
- package/esm/utils/tuple/includes.js +2 -0
- package/esm/utils/tuple/includes.js.map +1 -0
- package/esm/utils/tuple/index.d.ts +4 -0
- package/esm/utils/tuple/index.d.ts.map +1 -0
- package/esm/utils/tuple/index.js +6 -0
- package/esm/utils/tuple/index.js.map +1 -0
- package/package.json +5 -5
- package/script/main/expect/index.d.ts +31 -0
- package/script/main/expect/index.d.ts.map +1 -0
- package/script/main/{async.js → expect/index.js} +1 -1
- package/script/main/expect/index.js.map +1 -0
- package/script/main/expect/to/be.d.ts +23 -0
- package/script/main/expect/to/be.d.ts.map +1 -0
- package/script/main/{type/set.js → expect/to/be.js} +1 -1
- package/script/main/expect/to/be.js.map +1 -0
- package/script/main/expect/to/equal.d.ts +26 -0
- package/script/main/expect/to/equal.d.ts.map +1 -0
- package/script/main/expect/to/equal.js +3 -0
- package/script/main/expect/to/equal.js.map +1 -0
- package/script/main/expect/to/extend.d.ts +31 -0
- package/script/main/expect/to/extend.d.ts.map +1 -0
- package/script/main/expect/to/extend.js +3 -0
- package/script/main/expect/to/extend.js.map +1 -0
- package/script/main/expect/to/have-key.d.ts +38 -0
- package/script/main/expect/to/have-key.d.ts.map +1 -0
- package/script/main/expect/to/have-key.js +3 -0
- package/script/main/expect/to/have-key.js.map +1 -0
- package/script/main/expect/to/index.d.ts +13 -0
- package/script/main/expect/to/index.d.ts.map +1 -0
- package/script/main/expect/to/index.js +3 -0
- package/script/main/expect/to/index.js.map +1 -0
- package/script/main/expect/to/proper-extends.d.ts +21 -0
- package/script/main/expect/to/proper-extends.d.ts.map +1 -0
- package/script/main/expect/to/proper-extends.js +3 -0
- package/script/main/expect/to/proper-extends.js.map +1 -0
- package/script/main/index.d.ts +26 -11
- package/script/main/index.d.ts.map +1 -1
- package/script/main/index.js +24 -27
- package/script/main/index.js.map +1 -1
- package/script/main/noop.d.ts +27 -0
- package/script/main/noop.d.ts.map +1 -0
- package/script/{test-utils/index.js → main/noop.js} +1 -14
- package/script/main/noop.js.map +1 -0
- package/script/utils/compare/assignable.d.ts +30 -0
- package/script/utils/compare/assignable.d.ts.map +1 -0
- package/script/utils/compare/assignable.js +3 -0
- package/script/utils/compare/assignable.js.map +1 -0
- package/script/utils/compare/exact.d.ts +50 -0
- package/script/utils/compare/exact.d.ts.map +1 -0
- package/script/utils/compare/exact.js +3 -0
- package/script/utils/compare/exact.js.map +1 -0
- package/script/utils/compare/extends.d.ts +46 -0
- package/script/utils/compare/extends.d.ts.map +1 -0
- package/script/{main/boolean.js → utils/compare/extends.js} +1 -1
- package/script/utils/compare/extends.js.map +1 -0
- package/script/utils/compare/index.d.ts +5 -0
- package/script/utils/compare/index.d.ts.map +1 -0
- package/script/utils/compare/index.js +23 -0
- package/script/utils/compare/index.js.map +1 -0
- package/script/utils/compare/overlap.d.ts +47 -0
- package/script/utils/compare/overlap.d.ts.map +1 -0
- package/script/{main/control.js → utils/compare/overlap.js} +1 -1
- package/script/utils/compare/overlap.js.map +1 -0
- package/script/utils/index.d.ts +11 -0
- package/script/utils/index.d.ts.map +1 -0
- package/script/utils/index.js +29 -0
- package/script/utils/index.js.map +1 -0
- package/script/utils/logic/assert.d.ts +18 -0
- package/script/utils/logic/assert.d.ts.map +1 -0
- package/script/utils/logic/assert.js +3 -0
- package/script/utils/logic/assert.js.map +1 -0
- package/script/utils/logic/if.d.ts +37 -0
- package/script/utils/logic/if.d.ts.map +1 -0
- package/script/{main/key.js → utils/logic/if.js} +1 -1
- package/script/utils/logic/if.js.map +1 -0
- package/script/utils/logic/index.d.ts +4 -0
- package/script/utils/logic/index.d.ts.map +1 -0
- package/script/utils/logic/index.js +22 -0
- package/script/utils/logic/index.js.map +1 -0
- package/{esm/main/control.d.ts → script/utils/logic/switch.d.ts} +15 -40
- package/script/utils/logic/switch.d.ts.map +1 -0
- package/script/utils/logic/switch.js +3 -0
- package/script/utils/logic/switch.js.map +1 -0
- package/script/utils/misc.d.ts +34 -0
- package/script/utils/misc.d.ts.map +1 -0
- package/script/{main/json.js → utils/misc.js} +1 -1
- package/script/utils/misc.js.map +1 -0
- package/script/utils/object/index.d.ts +4 -0
- package/script/utils/object/index.d.ts.map +1 -0
- package/script/{main/type → utils/object}/index.js +3 -2
- package/script/utils/object/index.js.map +1 -0
- package/{esm/main/key.d.ts → script/utils/object/keys.d.ts} +34 -34
- package/script/utils/object/keys.d.ts.map +1 -0
- package/script/{main/doc.js → utils/object/keys.js} +1 -1
- package/script/utils/object/keys.js.map +1 -0
- package/script/utils/object/pick.d.ts +16 -0
- package/script/utils/object/pick.d.ts.map +1 -0
- package/script/utils/object/pick.js +3 -0
- package/script/utils/object/pick.js.map +1 -0
- package/script/utils/object/props.d.ts +17 -0
- package/script/utils/object/props.d.ts.map +1 -0
- package/script/utils/object/props.js +3 -0
- package/script/utils/object/props.js.map +1 -0
- package/script/utils/tuple/append.d.ts +17 -0
- package/script/utils/tuple/append.d.ts.map +1 -0
- package/script/utils/tuple/append.js +3 -0
- package/script/utils/tuple/append.js.map +1 -0
- package/script/utils/tuple/concat.d.ts +31 -0
- package/script/utils/tuple/concat.d.ts.map +1 -0
- package/script/utils/tuple/concat.js +3 -0
- package/script/utils/tuple/concat.js.map +1 -0
- package/script/utils/tuple/includes.d.ts +20 -0
- package/script/utils/tuple/includes.d.ts.map +1 -0
- package/script/utils/tuple/includes.js +3 -0
- package/script/utils/tuple/includes.js.map +1 -0
- package/script/utils/tuple/index.d.ts +4 -0
- package/script/utils/tuple/index.d.ts.map +1 -0
- package/script/utils/tuple/index.js +22 -0
- package/script/utils/tuple/index.js.map +1 -0
- package/esm/main/async.d.ts +0 -13
- package/esm/main/async.d.ts.map +0 -1
- package/esm/main/async.js +0 -2
- package/esm/main/async.js.map +0 -1
- package/esm/main/boolean.d.ts +0 -59
- package/esm/main/boolean.d.ts.map +0 -1
- package/esm/main/boolean.js +0 -2
- package/esm/main/boolean.js.map +0 -1
- package/esm/main/control.d.ts.map +0 -1
- package/esm/main/control.js +0 -2
- package/esm/main/control.js.map +0 -1
- package/esm/main/doc.d.ts +0 -56
- package/esm/main/doc.d.ts.map +0 -1
- package/esm/main/doc.js +0 -2
- package/esm/main/doc.js.map +0 -1
- package/esm/main/function.d.ts +0 -27
- package/esm/main/function.d.ts.map +0 -1
- package/esm/main/function.js +0 -2
- package/esm/main/function.js.map +0 -1
- package/esm/main/json.d.ts +0 -44
- package/esm/main/json.d.ts.map +0 -1
- package/esm/main/json.js +0 -2
- package/esm/main/json.js.map +0 -1
- package/esm/main/key.d.ts.map +0 -1
- package/esm/main/key.js +0 -2
- package/esm/main/key.js.map +0 -1
- package/esm/main/object.d.ts +0 -120
- package/esm/main/object.d.ts.map +0 -1
- package/esm/main/object.js +0 -2
- package/esm/main/object.js.map +0 -1
- package/esm/main/tuple.d.ts +0 -64
- package/esm/main/tuple.d.ts.map +0 -1
- package/esm/main/tuple.js +0 -2
- package/esm/main/tuple.js.map +0 -1
- package/esm/main/type/compare.d.ts +0 -169
- package/esm/main/type/compare.d.ts.map +0 -1
- package/esm/main/type/compare.js +0 -2
- package/esm/main/type/compare.js.map +0 -1
- package/esm/main/type/index.d.ts +0 -3
- package/esm/main/type/index.d.ts.map +0 -1
- package/esm/main/type/index.js +0 -5
- package/esm/main/type/index.js.map +0 -1
- package/esm/main/type/set.d.ts +0 -34
- package/esm/main/type/set.d.ts.map +0 -1
- package/esm/main/type/set.js +0 -2
- package/esm/main/type/set.js.map +0 -1
- package/esm/main/typed-array.d.ts +0 -5
- package/esm/main/typed-array.d.ts.map +0 -1
- package/esm/main/typed-array.js +0 -2
- package/esm/main/typed-array.js.map +0 -1
- package/esm/test-utils/compare.d.ts +0 -81
- package/esm/test-utils/compare.d.ts.map +0 -1
- package/esm/test-utils/compare.js +0 -2
- package/esm/test-utils/compare.js.map +0 -1
- package/esm/test-utils/expect.d.ts +0 -278
- package/esm/test-utils/expect.d.ts.map +0 -1
- package/esm/test-utils/expect.js +0 -2
- package/esm/test-utils/expect.js.map +0 -1
- package/esm/test-utils/index.d.ts +0 -77
- package/esm/test-utils/index.d.ts.map +0 -1
- package/esm/test-utils/index.js.map +0 -1
- package/script/main/async.d.ts +0 -13
- package/script/main/async.d.ts.map +0 -1
- package/script/main/async.js.map +0 -1
- package/script/main/boolean.d.ts +0 -59
- package/script/main/boolean.d.ts.map +0 -1
- package/script/main/boolean.js.map +0 -1
- package/script/main/control.d.ts.map +0 -1
- package/script/main/control.js.map +0 -1
- package/script/main/doc.d.ts +0 -56
- package/script/main/doc.d.ts.map +0 -1
- package/script/main/doc.js.map +0 -1
- package/script/main/function.d.ts +0 -27
- package/script/main/function.d.ts.map +0 -1
- package/script/main/function.js +0 -3
- package/script/main/function.js.map +0 -1
- package/script/main/json.d.ts +0 -44
- package/script/main/json.d.ts.map +0 -1
- package/script/main/json.js.map +0 -1
- package/script/main/key.d.ts.map +0 -1
- package/script/main/key.js.map +0 -1
- package/script/main/object.d.ts +0 -120
- package/script/main/object.d.ts.map +0 -1
- package/script/main/object.js +0 -3
- package/script/main/object.js.map +0 -1
- package/script/main/tuple.d.ts +0 -64
- package/script/main/tuple.d.ts.map +0 -1
- package/script/main/tuple.js +0 -3
- package/script/main/tuple.js.map +0 -1
- package/script/main/type/compare.d.ts +0 -169
- package/script/main/type/compare.d.ts.map +0 -1
- package/script/main/type/compare.js +0 -3
- package/script/main/type/compare.js.map +0 -1
- package/script/main/type/index.d.ts +0 -3
- package/script/main/type/index.d.ts.map +0 -1
- package/script/main/type/index.js.map +0 -1
- package/script/main/type/set.d.ts +0 -34
- package/script/main/type/set.d.ts.map +0 -1
- package/script/main/type/set.js.map +0 -1
- package/script/main/typed-array.d.ts +0 -5
- package/script/main/typed-array.d.ts.map +0 -1
- package/script/main/typed-array.js +0 -3
- package/script/main/typed-array.js.map +0 -1
- package/script/test-utils/compare.d.ts +0 -81
- package/script/test-utils/compare.d.ts.map +0 -1
- package/script/test-utils/compare.js +0 -3
- package/script/test-utils/compare.js.map +0 -1
- package/script/test-utils/expect.d.ts +0 -278
- package/script/test-utils/expect.d.ts.map +0 -1
- package/script/test-utils/expect.js +0 -3
- package/script/test-utils/expect.js.map +0 -1
- package/script/test-utils/index.d.ts +0 -77
- package/script/test-utils/index.d.ts.map +0 -1
- 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>().
|
|
13
|
-
expect<never>().
|
|
14
|
-
expect<never>().
|
|
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 '
|
|
17
|
-
expect<never>().
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
69
|
-
import { Exact } from 'https://raw.githubusercontent.com/Leawind/lay-sing/refs/heads/main/src/
|
|
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
|
|
79
|
+
import { expect } from 'lay-sing'
|
|
82
80
|
```
|
|
83
81
|
|
|
84
|
-
The
|
|
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>().
|
|
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 `.
|
|
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>().
|
|
102
|
-
> + expect<true>().
|
|
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 }>().
|
|
109
|
+
expect<keyof { a: 2 }>().to.be<'a'>().pass
|
|
112
110
|
|
|
113
111
|
// Passes if A extends B
|
|
114
|
-
expect<12138>().
|
|
112
|
+
expect<12138>().to.extend<number>().pass
|
|
115
113
|
|
|
116
114
|
// Passes if mutually assignable
|
|
117
|
-
expect<{ a: 1; b: 2 }>().
|
|
115
|
+
expect<{ a: 1; b: 2 }>().to.equal<{ a: 1 } & { b: 2 }>().pass
|
|
118
116
|
|
|
119
117
|
// Test property existence
|
|
120
|
-
expect<{ name: string }>().
|
|
118
|
+
expect<{ name: string }>().to.haveKey<'name'>().pass
|
|
121
119
|
```
|
|
122
120
|
|
|
123
121
|
Aliases:
|
|
124
122
|
|
|
125
123
|
```ts
|
|
126
|
-
expect<never>().
|
|
127
|
-
expect<never>().
|
|
124
|
+
expect<never>().to.be<never>().pass
|
|
125
|
+
expect<never>().to.be.never
|
|
128
126
|
|
|
129
|
-
expect<'hello'>().
|
|
130
|
-
expect<'hello'>().
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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"]}
|
package/esm/main/index.d.ts
CHANGED
|
@@ -3,15 +3,30 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
package/esm/main/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
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
|
-
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
package/esm/main/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
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
|
-
|
|
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"]}
|