lay-sing 0.2.1 → 0.3.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 +14 -18
- package/esm/{test-utils → main}/expect.d.ts +34 -19
- package/esm/main/expect.d.ts.map +1 -0
- package/esm/main/expect.js.map +1 -0
- package/esm/main/index.d.ts +24 -11
- package/esm/main/index.d.ts.map +1 -1
- package/esm/main/index.js +5 -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 +10 -0
- package/esm/utils/index.d.ts.map +1 -0
- package/esm/utils/index.js +12 -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} +14 -39
- 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/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/{test-utils → main}/expect.d.ts +34 -19
- package/script/main/expect.d.ts.map +1 -0
- package/script/main/expect.js.map +1 -0
- package/script/main/index.d.ts +24 -11
- package/script/main/index.d.ts.map +1 -1
- package/script/main/index.js +8 -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/{main/async.js → utils/compare/exact.js} +1 -1
- 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 +10 -0
- package/script/utils/index.d.ts.map +1 -0
- package/script/utils/index.js +28 -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/type/set.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} +14 -39
- 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/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/json.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/{main/key.js → utils/object/pick.js} +1 -1
- 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/{main/doc.js → utils/object/props.js} +1 -1
- 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.map +0 -1
- 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.map +0 -1
- 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/esm/{test-utils → main}/expect.js +0 -0
- /package/script/{test-utils → main}/expect.js +0 -0
package/README.md
CHANGED
|
@@ -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,13 +75,11 @@ 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
|
|
|
@@ -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)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Exact, Extends, If, IfTupleIncludes, MutuallyAssignable, ProperExtend, SafePick } from '../
|
|
1
|
+
import type { Exact, Extends, If, IfTupleIncludes, MutuallyAssignable, ProperExtend, SafePick } from '../utils/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Represents the result of a type assertion based on a boolean condition.
|
|
4
4
|
*
|
|
@@ -32,7 +32,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
32
32
|
*
|
|
33
33
|
* @example
|
|
34
34
|
* ```ts
|
|
35
|
-
* import { expect } from '@leawind/lay-sing
|
|
35
|
+
* import { expect } from '@leawind/lay-sing'
|
|
36
36
|
*
|
|
37
37
|
* expect<any>().toBe<any>().success
|
|
38
38
|
* expect<never>().toBe<never>().success
|
|
@@ -40,6 +40,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
42
|
toBe<U>(): TypeAssertionResult<Exact<T, U>, ExpectType<T, H>>;
|
|
43
|
+
toBe<U>(_: U): TypeAssertionResult<Exact<T, U>, ExpectType<T, H>>;
|
|
43
44
|
/**
|
|
44
45
|
* Tests if the current type is mutually assignable with the provided type U.
|
|
45
46
|
*
|
|
@@ -53,13 +54,14 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
53
54
|
*
|
|
54
55
|
* @example
|
|
55
56
|
* ```ts
|
|
56
|
-
* import { expect } from '@leawind/lay-sing
|
|
57
|
+
* import { expect } from '@leawind/lay-sing'
|
|
57
58
|
*
|
|
58
59
|
* expect<{ a: 1; b: 2 }>().toEqual<{ a: 1 } & { b: 2 }>().success
|
|
59
60
|
* expect<1>().toEqual<1 | 2>().fail
|
|
60
61
|
* ```
|
|
61
62
|
*/
|
|
62
63
|
toEqual<U>(): TypeAssertionResult<MutuallyAssignable<T, U>, ExpectType<T, H>>;
|
|
64
|
+
toEqual<U>(_: U): TypeAssertionResult<MutuallyAssignable<T, U>, ExpectType<T, H>>;
|
|
63
65
|
/**
|
|
64
66
|
* Tests if the current type T extends the provided type U.
|
|
65
67
|
*
|
|
@@ -67,7 +69,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
67
69
|
*
|
|
68
70
|
* @example
|
|
69
71
|
* ```ts
|
|
70
|
-
* import { expect } from '@leawind/lay-sing
|
|
72
|
+
* import { expect } from '@leawind/lay-sing'
|
|
71
73
|
*
|
|
72
74
|
* expect<3.14>().toExtend<number>().success
|
|
73
75
|
* expect<2>().toExtend<string>().fail
|
|
@@ -75,6 +77,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
75
77
|
* ```
|
|
76
78
|
*/
|
|
77
79
|
toExtend<U>(): TypeAssertionResult<Extends<T, U>, ExpectType<T, H>>;
|
|
80
|
+
toExtend<U>(_: U): TypeAssertionResult<Extends<T, U>, ExpectType<T, H>>;
|
|
78
81
|
/**
|
|
79
82
|
* Tests if the current type T properly extends the provided type U (extends but is not the same).
|
|
80
83
|
*
|
|
@@ -82,7 +85,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
82
85
|
*
|
|
83
86
|
* @example
|
|
84
87
|
* ```ts
|
|
85
|
-
* import { expect } from '@leawind/lay-sing
|
|
88
|
+
* import { expect } from '@leawind/lay-sing'
|
|
86
89
|
*
|
|
87
90
|
* expect<2>().toProperExtend<number>().success
|
|
88
91
|
* expect<'a' | 'b'>().toProperExtend<string>().success
|
|
@@ -90,6 +93,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
90
93
|
* ```
|
|
91
94
|
*/
|
|
92
95
|
toProperExtend<U>(): TypeAssertionResult<ProperExtend<T, U>, ExpectType<T, H>>;
|
|
96
|
+
toProperExtend<U>(_: U): TypeAssertionResult<ProperExtend<T, U>, ExpectType<T, H>>;
|
|
93
97
|
/**
|
|
94
98
|
* Tests if the current type `T` has a property with key `K`.
|
|
95
99
|
*
|
|
@@ -103,7 +107,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
103
107
|
* ### Examples
|
|
104
108
|
*
|
|
105
109
|
* ```ts
|
|
106
|
-
* import { expect } from '@leawind/lay-sing
|
|
110
|
+
* import { expect } from '@leawind/lay-sing'
|
|
107
111
|
*
|
|
108
112
|
* type WithProp = { prop: string; another: number; may?: 5 }
|
|
109
113
|
*
|
|
@@ -120,7 +124,18 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
120
124
|
never,
|
|
121
125
|
any
|
|
122
126
|
], K, never, TypeAssertionResult<Extends<K, keyof T>, ExpectType<T, H>>>;
|
|
127
|
+
toHaveKey<K extends PropertyKey>(_: K): IfTupleIncludes<[
|
|
128
|
+
never,
|
|
129
|
+
any
|
|
130
|
+
], K, never, TypeAssertionResult<Extends<K, keyof T>, ExpectType<T, H>>>;
|
|
123
131
|
};
|
|
132
|
+
type ExpectFunction<T, H extends PropertyKey = never> = Exact<T, any> extends true ? unknown : Exact<T, never> extends true ? unknown : [T] extends [(...args: infer Args) => infer R] ? {
|
|
133
|
+
argsType(): ExpectType<Args, H>;
|
|
134
|
+
returnType(): ExpectType<R, H>;
|
|
135
|
+
} : [T] extends [new (...args: infer Args) => infer R] ? {
|
|
136
|
+
argsType(): ExpectType<Args, H>;
|
|
137
|
+
returnType(): ExpectType<R, H>;
|
|
138
|
+
} : unknown;
|
|
124
139
|
/**
|
|
125
140
|
* Type-level testing utility that allows checking various relationships between types.
|
|
126
141
|
* Provides methods to test type equality, extension, properties, and more.
|
|
@@ -130,7 +145,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
130
145
|
*
|
|
131
146
|
* @example
|
|
132
147
|
* ```ts
|
|
133
|
-
* import { expect } from '@leawind/lay-sing
|
|
148
|
+
* import { expect } from '@leawind/lay-sing'
|
|
134
149
|
*
|
|
135
150
|
* // Test if two types are identical
|
|
136
151
|
* expect<number>().toBe<number>().success
|
|
@@ -142,7 +157,7 @@ type ExpectTypeMethods<T, H extends PropertyKey = never> = {
|
|
|
142
157
|
* expect<{name: string}>().toHaveKey<'name'>().success
|
|
143
158
|
* ```
|
|
144
159
|
*/
|
|
145
|
-
export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMethods<T, H> & {
|
|
160
|
+
export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMethods<T, H> & ExpectFunction<T, H> & {
|
|
146
161
|
T: T;
|
|
147
162
|
inspect: {
|
|
148
163
|
[K in keyof T]: T[K];
|
|
@@ -154,7 +169,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
154
169
|
*
|
|
155
170
|
* @example
|
|
156
171
|
* ```ts
|
|
157
|
-
* import { expect } from '@leawind/lay-sing
|
|
172
|
+
* import { expect } from '@leawind/lay-sing'
|
|
158
173
|
*
|
|
159
174
|
* expect<3.14>().toExtendNumber
|
|
160
175
|
* ```
|
|
@@ -166,7 +181,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
166
181
|
*
|
|
167
182
|
* @example
|
|
168
183
|
* ```ts
|
|
169
|
-
* import { expect } from '@leawind/lay-sing
|
|
184
|
+
* import { expect } from '@leawind/lay-sing'
|
|
170
185
|
*
|
|
171
186
|
* expect<'hello'>().toExtendString
|
|
172
187
|
* ```
|
|
@@ -178,7 +193,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
178
193
|
*
|
|
179
194
|
* @example
|
|
180
195
|
* ```ts
|
|
181
|
-
* import { expect } from '@leawind/lay-sing
|
|
196
|
+
* import { expect } from '@leawind/lay-sing'
|
|
182
197
|
*
|
|
183
198
|
* expect<true>().toExtendBoolean
|
|
184
199
|
* ```
|
|
@@ -189,7 +204,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
189
204
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = any`
|
|
190
205
|
*
|
|
191
206
|
* ```ts
|
|
192
|
-
* import { expect } from '@leawind/lay-sing
|
|
207
|
+
* import { expect } from '@leawind/lay-sing'
|
|
193
208
|
*
|
|
194
209
|
* expect<any>().toBeAny
|
|
195
210
|
* expect<any>().toBe<any>().success
|
|
@@ -200,7 +215,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
200
215
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = never`
|
|
201
216
|
*
|
|
202
217
|
* ```ts
|
|
203
|
-
* import { expect } from '@leawind/lay-sing
|
|
218
|
+
* import { expect } from '@leawind/lay-sing'
|
|
204
219
|
*
|
|
205
220
|
* expect<never>().toBeNever
|
|
206
221
|
* expect<never>().toBe<never>().success
|
|
@@ -211,7 +226,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
211
226
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = unknown`
|
|
212
227
|
*
|
|
213
228
|
* ```ts
|
|
214
|
-
* import { expect } from '@leawind/lay-sing
|
|
229
|
+
* import { expect } from '@leawind/lay-sing'
|
|
215
230
|
*
|
|
216
231
|
* expect<unknown>().toBeUnknown
|
|
217
232
|
* expect<unknown>().toBe<unknown>().success
|
|
@@ -222,7 +237,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
222
237
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = void`
|
|
223
238
|
*
|
|
224
239
|
* ```ts
|
|
225
|
-
* import { expect } from '@leawind/lay-sing
|
|
240
|
+
* import { expect } from '@leawind/lay-sing'
|
|
226
241
|
*
|
|
227
242
|
* expect<void>().toBeVoid
|
|
228
243
|
* expect<void>().toBe<void>().success
|
|
@@ -233,7 +248,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
233
248
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = null`
|
|
234
249
|
*
|
|
235
250
|
* ```ts
|
|
236
|
-
* import { expect } from '@leawind/lay-sing
|
|
251
|
+
* import { expect } from '@leawind/lay-sing'
|
|
237
252
|
*
|
|
238
253
|
* expect<null>().toBeNull
|
|
239
254
|
* expect<null>().toBe<null>().success
|
|
@@ -244,7 +259,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
244
259
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = undefined`
|
|
245
260
|
*
|
|
246
261
|
* ```ts
|
|
247
|
-
* import { expect } from '@leawind/lay-sing
|
|
262
|
+
* import { expect } from '@leawind/lay-sing'
|
|
248
263
|
*
|
|
249
264
|
* expect<undefined>().toBeUndefined
|
|
250
265
|
* expect<undefined>().toBe<undefined>().success
|
|
@@ -255,7 +270,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
255
270
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = true`
|
|
256
271
|
*
|
|
257
272
|
* ```ts
|
|
258
|
-
* import { expect } from '@leawind/lay-sing
|
|
273
|
+
* import { expect } from '@leawind/lay-sing'
|
|
259
274
|
*
|
|
260
275
|
* expect<true>().toBeTrue
|
|
261
276
|
* expect<true>().toBe<true>().success
|
|
@@ -266,7 +281,7 @@ export type ExpectType<T, H extends PropertyKey = never> = Omit<(ExpectTypeMetho
|
|
|
266
281
|
* Alias for {@link ExpectTypeMethods.toBe} where `U = false`
|
|
267
282
|
*
|
|
268
283
|
* ```ts
|
|
269
|
-
* import { expect } from '@leawind/lay-sing
|
|
284
|
+
* import { expect } from '@leawind/lay-sing'
|
|
270
285
|
*
|
|
271
286
|
* expect<false>().toBeFalse
|
|
272
287
|
* expect<false>().toBe<false>().success
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/main/expect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.js","sourceRoot":"","sources":["../../src/main/expect.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n Exact,\n Extends,\n If,\n IfTupleIncludes,\n MutuallyAssignable,\n ProperExtend,\n SafePick,\n} from '../utils/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 `success` 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 success: 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 success, use `.success`\n */\n fail: R\n }\n : never\n\ntype ExpectTypeMethods<T, H extends PropertyKey = never> = {\n /**\n * Tests if the current type is exactly the same as the provided type U.\n *\n * @template U The type to compare with\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<any>().toBe<any>().success\n * expect<never>().toBe<never>().success\n * expect<false>().toBe<true>().fail\n * ```\n */\n toBe<U>(): TypeAssertionResult<Exact<T, U>, ExpectType<T, H>>\n toBe<U>(_: U): TypeAssertionResult<Exact<T, U>, ExpectType<T, H>>\n\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 }>().toEqual<{ a: 1 } & { b: 2 }>().success\n * expect<1>().toEqual<1 | 2>().fail\n * ```\n */\n toEqual<U>(): TypeAssertionResult<MutuallyAssignable<T, U>, ExpectType<T, H>>\n toEqual<U>(_: U): TypeAssertionResult<MutuallyAssignable<T, U>, ExpectType<T, H>>\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>().toExtend<number>().success\n * expect<2>().toExtend<string>().fail\n * expect<'hello'>().toExtend<string>().success\n * ```\n */\n toExtend<U>(): TypeAssertionResult<Extends<T, U>, ExpectType<T, H>>\n toExtend<U>(_: U): TypeAssertionResult<Extends<T, U>, ExpectType<T, H>>\n\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>().toProperExtend<number>().success\n * expect<'a' | 'b'>().toProperExtend<string>().success\n * expect<number>().toProperExtend<number>().fail\n * ```\n */\n toProperExtend<U>(): TypeAssertionResult<ProperExtend<T, U>, ExpectType<T, H>>\n toProperExtend<U>(_: U): TypeAssertionResult<ProperExtend<T, U>, ExpectType<T, H>>\n\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>().toHaveKey<'prop'>().success\n * expect<WithProp>().toHaveKey<'missing'>().fail\n *\n * // Union type checks\n * expect<WithProp>().toHaveKey<'prop' | 'another'>().success\n * expect<WithProp>().toHaveKey<'may' | 'unexist'>().fail\n * ```\n */\n toHaveKey<K extends PropertyKey>(): IfTupleIncludes<\n [never, any],\n K,\n never,\n TypeAssertionResult<Extends<K, keyof T>, ExpectType<T, H>>\n >\n toHaveKey<K extends PropertyKey>(_: K): IfTupleIncludes<\n [never, any],\n K,\n never,\n TypeAssertionResult<Extends<K, keyof T>, ExpectType<T, H>>\n >\n}\n\ntype ExpectFunction<T, H extends PropertyKey = never> = Exact<T, any> extends true ? unknown\n : Exact<T, never> extends true ? unknown\n : [T] extends [(...args: infer Args) => infer R] ? {\n argsType(): ExpectType<Args, H>\n returnType(): ExpectType<R, H>\n }\n : [T] extends [new (...args: infer Args) => infer R] ? {\n argsType(): ExpectType<Args, H>\n returnType(): ExpectType<R, H>\n }\n : unknown\n\n/**\n * Type-level testing utility that allows checking various relationships between types.\n * Provides methods to test type equality, extension, properties, and more.\n *\n * @template T The type being tested\n * @template H Hidden property keys that are already used (internal tracking)\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * // Test if two types are identical\n * expect<number>().toBe<number>().success\n * expect<number>().toBe<string>().fail\n * // Test if one type extends another\n * expect<2>().toExtend<number>().success\n * expect<2>().toExtend<string>().fail\n * // Test if type has a specific property\n * expect<{name: string}>().toHaveKey<'name'>().success\n * ```\n */\nexport type ExpectType<T, H extends PropertyKey = never> = Omit<\n (\n & ExpectTypeMethods<T, H>\n & ExpectFunction<T, H>\n & {\n T: T\n inspect: { [K in keyof T]: T[K] }\n }\n & SafePick<\n {\n /**\n * Tests if the current type extends the Number primitive type.\n * Available only if the current type extends number.\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<3.14>().toExtendNumber\n * ```\n */\n toExtendNumber: ExpectType<T, H | 'toExtendNumber' | 'toExtend'>\n\n /**\n * Tests if the current type extends the String primitive type.\n * Available only if the current type extends string.\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<'hello'>().toExtendString\n * ```\n */\n toExtendString: ExpectType<T, H | 'toExtendString' | 'toExtend'>\n\n /**\n * Tests if the current type extends the Boolean primitive type.\n * Available only if the current type extends boolean.\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<true>().toExtendBoolean\n * ```\n */\n toExtendBoolean: ExpectType<T, H | 'toExtendBoolean' | 'toExtend'>\n },\n | If<Extends<T, number>, 'toExtendNumber'>\n | If<Extends<T, string>, 'toExtendString'>\n | If<Extends<T, boolean>, 'toExtendBoolean'>\n >\n & SafePick<\n {\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = any`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<any>().toBeAny\n * expect<any>().toBe<any>().success\n * ```\n */\n toBeAny: ExpectType<T, H | 'toBeAny' | 'toBe'>\n\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = never`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<never>().toBeNever\n * expect<never>().toBe<never>().success\n * ```\n */\n toBeNever: ExpectType<T, H | 'toBeNever' | 'toBe'>\n\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = unknown`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<unknown>().toBeUnknown\n * expect<unknown>().toBe<unknown>().success\n * ```\n */\n toBeUnknown: ExpectType<T, H | 'toBeUnknown' | 'toBe'>\n\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = void`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<void>().toBeVoid\n * expect<void>().toBe<void>().success\n * ```\n */\n toBeVoid: ExpectType<T, H | 'toBeVoid' | 'toBe'>\n\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = null`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<null>().toBeNull\n * expect<null>().toBe<null>().success\n * ```\n */\n toBeNull: ExpectType<T, H | 'toBeNull' | 'toBe'>\n\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = undefined`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<undefined>().toBeUndefined\n * expect<undefined>().toBe<undefined>().success\n * ```\n */\n toBeUndefined: ExpectType<T, H | 'toBeUndefined' | 'toBe'>\n\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = true`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<true>().toBeTrue\n * expect<true>().toBe<true>().success\n * ```\n */\n toBeTrue: ExpectType<T, H | 'toBeTrue' | 'toBe' | 'toExtendBoolean'>\n\n /**\n * Alias for {@link ExpectTypeMethods.toBe} where `U = false`\n *\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<false>().toBeFalse\n * expect<false>().toBe<false>().success\n * ```\n */\n toBeFalse: ExpectType<T, H | 'toBeFalse' | 'toBe' | 'toExtendBoolean'>\n },\n | If<Exact<T, any>, 'toBeAny'>\n | If<Exact<T, never>, 'toBeNever'>\n | If<Exact<T, unknown>, 'toBeUnknown'>\n | If<Exact<T, void>, 'toBeVoid'>\n | If<Exact<T, null>, 'toBeNull'>\n | If<Exact<T, undefined>, 'toBeUndefined'>\n | If<Exact<T, true>, 'toBeTrue'>\n | If<Exact<T, false>, 'toBeFalse'>\n >\n ),\n H\n>\n"]}
|
package/esm/main/index.d.ts
CHANGED
|
@@ -3,15 +3,28 @@
|
|
|
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.js';
|
|
7
|
+
export type { ExpectType } from './expect.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>().toBe<number>().success
|
|
22
|
+
* expect<number>().toBe<string>().fail
|
|
23
|
+
* // Test if one type extends another
|
|
24
|
+
* expect<3.14>().toExtend<number>().success
|
|
25
|
+
* expect<2>().toExtend<string>().fail
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function expect<T>(): ExpectType<T>;
|
|
29
|
+
export declare function expect<T>(_: T): ExpectType<T>;
|
|
17
30
|
//# 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,aAAa,CAAA;AAG7C,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAA;AAC1C,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA"}
|
package/esm/main/index.js
CHANGED
|
@@ -3,17 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
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
|
+
export function expect() {
|
|
9
|
+
return NOOP;
|
|
10
|
+
}
|
|
19
11
|
//# 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;AAuBhC,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["/**\n * [Full API documentation is available on JSR](https://jsr.io/@leawind/lay-sing/doc)\n *\n * @module\n */\n\nimport type { ExpectType } from './expect.js'\nimport { NOOP } from './noop.js'\n\nexport type { ExpectType } from './expect.js'\nexport { NOOP } from './noop.js'\n\n/**\n * Creates an instance of ExpectType to perform type-level assertions on the given type.\n * This function enables testing various type relationships at compile time.\n * NOTE: This function does nothing at runtime and is purely for type-level testing.\n *\n * @template T The type to be tested\n *\n * @returns An ExpectType instance with methods to test type relationships\n *\n * @example\n * ```ts\n * // Test exact type equality\n * expect<number>().toBe<number>().success\n * expect<number>().toBe<string>().fail\n * // Test if one type extends another\n * expect<3.14>().toExtend<number>().success\n * expect<2>().toExtend<string>().fail\n * ```\n */\nexport function expect<T>(): ExpectType<T>\nexport function expect<T>(_: T): ExpectType<T>\nexport function expect<T>(): ExpectType<T> {\n return NOOP\n}\n"]}
|
|
@@ -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"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether two types are mutually assignable.
|
|
3
|
+
*
|
|
4
|
+
* This is equivalent to checking that:
|
|
5
|
+
* - `A` extends `B`
|
|
6
|
+
* - `B` extends `A`
|
|
7
|
+
*
|
|
8
|
+
* In other words, the two types describe the same set of values,
|
|
9
|
+
* even if they are written differently.
|
|
10
|
+
*
|
|
11
|
+
* @template A - The first type to check
|
|
12
|
+
* @template B - The second type to check
|
|
13
|
+
* @template Yes - The result if types are mutually assignable (defaults to `true`)
|
|
14
|
+
* @template No - The result if types are not mutually assignable (defaults to `false`)
|
|
15
|
+
*
|
|
16
|
+
* ### Result
|
|
17
|
+
*
|
|
18
|
+
* - `Yes`: `A` and `B` are mutually assignable
|
|
19
|
+
* - `No`: Otherwise
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* type T1 = MutuallyAssignable<number, number> // true
|
|
24
|
+
* type T2 = MutuallyAssignable<1 | 2, 2 | 1> // true
|
|
25
|
+
* type F1 = MutuallyAssignable<string, number> // false
|
|
26
|
+
* type F2 = MutuallyAssignable<1, number> // false
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export type MutuallyAssignable<A, B, Yes = true, No = false> = [A] extends [B] ? [B] extends [A] ? Yes : No : No;
|
|
30
|
+
//# sourceMappingURL=assignable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assignable.d.ts","sourceRoot":"","sources":["../../../src/utils/compare/assignable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,MAAM,kBAAkB,CAC5B,CAAC,EACD,CAAC,EACD,GAAG,GAAG,IAAI,EACV,EAAE,GAAG,KAAK,IACR,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assignable.js","sourceRoot":"","sources":["../../../src/utils/compare/assignable.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Checks whether two types are mutually assignable.\n *\n * This is equivalent to checking that:\n * - `A` extends `B`\n * - `B` extends `A`\n *\n * In other words, the two types describe the same set of values,\n * even if they are written differently.\n *\n * @template A - The first type to check\n * @template B - The second type to check\n * @template Yes - The result if types are mutually assignable (defaults to `true`)\n * @template No - The result if types are not mutually assignable (defaults to `false`)\n *\n * ### Result\n *\n * - `Yes`: `A` and `B` are mutually assignable\n * - `No`: Otherwise\n *\n * @example\n * ```ts\n * type T1 = MutuallyAssignable<number, number> // true\n * type T2 = MutuallyAssignable<1 | 2, 2 | 1> // true\n * type F1 = MutuallyAssignable<string, number> // false\n * type F2 = MutuallyAssignable<1, number> // false\n * ```\n */\nexport type MutuallyAssignable<\n A,\n B,\n Yes = true,\n No = false,\n> = [A] extends [B] ? [B] extends [A] ? Yes : No : No\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether two types are exactly the same.
|
|
3
|
+
*
|
|
4
|
+
* **⚠️Important:** parameter `A` and `B` are not distributive. When they are union type, it does not check each member separately.
|
|
5
|
+
*
|
|
6
|
+
* @template A - The first type to compare
|
|
7
|
+
* @template B - The second type to compare
|
|
8
|
+
* @template Yes - The result if types are exactly the same (defaults to `true`)
|
|
9
|
+
* @template No - The result if types are not exactly the same (defaults to `false`)
|
|
10
|
+
*
|
|
11
|
+
* ### Result
|
|
12
|
+
*
|
|
13
|
+
* - `Yes`: `A` and `B` are exactly the same
|
|
14
|
+
* - `No`: Otherwise
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { expect } from '@leawind/lay-sing'
|
|
19
|
+
*
|
|
20
|
+
* expect<Exact<string, string>>().toBeTrue
|
|
21
|
+
* expect<Exact<never, never>>().toBeTrue
|
|
22
|
+
* expect<Exact<any, any>>().toBeTrue
|
|
23
|
+
*
|
|
24
|
+
* expect<Exact<{ a: 3 }, { a?: 3 }>>().toBeFalse
|
|
25
|
+
* expect<Exact<1 | 2, 1>>().toBeFalse
|
|
26
|
+
* expect<Exact<1, number>>().toBeFalse
|
|
27
|
+
* expect<Exact<() => void, () => undefined>>().toBeFalse
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export type Exact<A, B, Yes = true, No = false> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Yes : No;
|
|
31
|
+
/**
|
|
32
|
+
* Checks whether two types are not exactly the same.
|
|
33
|
+
*
|
|
34
|
+
* This is the logical negation of `Exact<A, B>`.
|
|
35
|
+
*
|
|
36
|
+
* @template A - The first type to compare
|
|
37
|
+
* @template B - The second type to compare
|
|
38
|
+
* @template Yes - The result if types are not exactly the same (defaults to `true`)
|
|
39
|
+
* @template No - The result if types are exactly the same (defaults to `false`)
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* type T1 = NotExact<number, string> // true
|
|
44
|
+
* type T2 = NotExact<1, number> // true
|
|
45
|
+
* type F1 = NotExact<number, number> // false
|
|
46
|
+
* type F2 = NotExact<1, 1> // false
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export type NotExact<A, B, Yes = true, No = false> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? No : Yes;
|
|
50
|
+
//# sourceMappingURL=exact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exact.d.ts","sourceRoot":"","sources":["../../../src/utils/compare/exact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,KAAK,CACf,CAAC,EACD,CAAC,EACD,GAAG,GAAG,IAAI,EACV,EAAE,GAAG,KAAK,IACR,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,CAAA;AAEpF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,QAAQ,CAClB,CAAC,EACD,CAAC,EACD,GAAG,GAAG,IAAI,EACV,EAAE,GAAG,KAAK,IACR,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exact.js","sourceRoot":"","sources":["../../../src/utils/compare/exact.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Checks whether two types are exactly the same.\n *\n * **⚠️Important:** parameter `A` and `B` are not distributive. When they are union type, it does not check each member separately.\n *\n * @template A - The first type to compare\n * @template B - The second type to compare\n * @template Yes - The result if types are exactly the same (defaults to `true`)\n * @template No - The result if types are not exactly the same (defaults to `false`)\n *\n * ### Result\n *\n * - `Yes`: `A` and `B` are exactly the same\n * - `No`: Otherwise\n *\n * @example\n * ```ts\n * import { expect } from '@leawind/lay-sing'\n *\n * expect<Exact<string, string>>().toBeTrue\n * expect<Exact<never, never>>().toBeTrue\n * expect<Exact<any, any>>().toBeTrue\n *\n * expect<Exact<{ a: 3 }, { a?: 3 }>>().toBeFalse\n * expect<Exact<1 | 2, 1>>().toBeFalse\n * expect<Exact<1, number>>().toBeFalse\n * expect<Exact<() => void, () => undefined>>().toBeFalse\n * ```\n */\nexport type Exact<\n A,\n B,\n Yes = true,\n No = false,\n> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Yes : No\n\n/**\n * Checks whether two types are not exactly the same.\n *\n * This is the logical negation of `Exact<A, B>`.\n *\n * @template A - The first type to compare\n * @template B - The second type to compare\n * @template Yes - The result if types are not exactly the same (defaults to `true`)\n * @template No - The result if types are exactly the same (defaults to `false`)\n *\n * @example\n * ```ts\n * type T1 = NotExact<number, string> // true\n * type T2 = NotExact<1, number> // true\n * type F1 = NotExact<number, number> // false\n * type F2 = NotExact<1, 1> // false\n * ```\n */\nexport type NotExact<\n A,\n B,\n Yes = true,\n No = false,\n> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? No : Yes\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Exact } from '../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether type `A` extends type `B`.
|
|
4
|
+
*
|
|
5
|
+
* **⚠️Important:** parameter `A` and `B` are not distributive. When they are union type, it treats them as a single entity.
|
|
6
|
+
*
|
|
7
|
+
* @template A - The type to check if it extends another type
|
|
8
|
+
* @template B - The type to check if `A` extends
|
|
9
|
+
* @template Yes - The result if `A` extends `B` (defaults to `true`)
|
|
10
|
+
* @template No - The result if `A` does not extend `B` (defaults to `false`)
|
|
11
|
+
*
|
|
12
|
+
* ### Result
|
|
13
|
+
*
|
|
14
|
+
* - `Yes`: `A` is assignable to `B`
|
|
15
|
+
* - `No`: Otherwise
|
|
16
|
+
*/
|
|
17
|
+
export type Extends<A, B, Yes = true, No = false> = [A] extends [B] ? Yes : No;
|
|
18
|
+
/**
|
|
19
|
+
* Checks whether type `A` is a *proper* subtype of type `B`.
|
|
20
|
+
*
|
|
21
|
+
* A proper extension means:
|
|
22
|
+
* - `A` extends `B`
|
|
23
|
+
* - `A` is not exactly the same type as `B`
|
|
24
|
+
*
|
|
25
|
+
* @template A - The type to check if it is a proper subtype
|
|
26
|
+
* @template B - The type to check against
|
|
27
|
+
* @template Yes - The result if `A` is a proper subtype of `B` (defaults to `true`)
|
|
28
|
+
* @template No - The result if `A` is not a proper subtype of `B` (defaults to `false`)
|
|
29
|
+
*
|
|
30
|
+
* ### Result
|
|
31
|
+
*
|
|
32
|
+
* - `Yes`: `A` is a proper subtype of `B`
|
|
33
|
+
* - `No`: Otherwise
|
|
34
|
+
*
|
|
35
|
+
* **Note:** the result will never be `boolean`.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* type T1 = ProperExtend<true, boolean> // true
|
|
40
|
+
* type T2 = ProperExtend<1, number> // true
|
|
41
|
+
* type F1 = ProperExtend<boolean, boolean> // false
|
|
42
|
+
* type F2 = ProperExtend<number, string> // false
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export type ProperExtend<A, B, Yes = true, No = false> = [A] extends [B] ? Exact<A, B> extends false ? Yes : No : No;
|
|
46
|
+
//# sourceMappingURL=extends.d.ts.map
|