From 44d7f67b7764f9d272dc6b799c4b8c8f34ea7ea1 Mon Sep 17 00:00:00 2001 From: Trevor Florence Date: Thu, 3 Nov 2022 09:31:22 -0600 Subject: [PATCH 1/7] Rewrite `Equal` to use the equality check from `ReadonlyEquivalent` exclusively. This is a breaking change as I opted to remove the types that were no longer needed. They are exported though so it's likely some people depend on them. This took a lot of tinkering. This topic and this equality check is discussed extensively at https://github.com/Microsoft/TypeScript/issues/27024 The main three work-arounds this implementation added are: 1. Explicitly handling `any` separately 2. Supporting identity unions 3. Supporting identity intersections The only known issue is this case: ```ts // @ts-expect-error This is the bug. expectTypeOf<{foo: number} & {bar: string}>().toEqualTypeOf<{foo: number; bar: string}>() ``` @shicks and I could not find a tweak to the `Equality` check to make this work. Instead, I added a workaround in the shape of a new `.simplified` modifier that works similar to `.not`: ```ts // The workaround is the new optional .simplified modifier. expectTypeOf<{foo: number} & {bar: string}>().simplified.toEqualTypeOf<{foo: number; bar: string}>() ``` I'm not entirely sure what to do with documenting `.simplified` because it's something you should never use unless you need it. The simplify operation tends to lose information about the types being tested (e.g., functions become `{}` and classes lose their constructors). I'll definitely update this PR to reference the `.simplified` modifier but I wanted to get a review on this approach first. One option would be to keep around all the `DeepBrand` stuff and to have `.deepBranded` or something being the modifier instead. That would have the benefit of preserving all the exported types making this less of a breaking change. --- src/index.ts | 50 +++-- test/errors.test.ts | 210 +++++++++++---------- test/types.test.ts | 444 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 588 insertions(+), 116 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2e4532ba..63aecfa0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -84,7 +84,15 @@ type ReadonlyEquivalent = Extends< export type Extends = IsNever extends true ? IsNever : [L] extends [R] ? true : false export type StrictExtends = Extends, DeepBrand> -export type Equal = And<[StrictExtends, StrictExtends]> +type StrictEqual = + (() => T extends (L & T) | T ? true : false) extends + (() => T extends (R & T) | T ? true : false) ? + IsNever extends IsNever ? true : false : false + +export type Equal = + Branded extends true + ? And<[StrictExtends, StrictExtends]> + : StrictEqual export type Params = Actual extends (...args: infer P) => any ? P : never export type ConstructorParams = Actual extends new (...args: infer P) => any @@ -95,7 +103,7 @@ export type ConstructorParams = Actual extends new (...args: infer P) => type MismatchArgs = Eq extends true ? [] : [never] -export interface ExpectTypeOf { +export interface ExpectTypeOf { toBeAny: (...MISMATCH: MismatchArgs, B>) => true toBeUnknown: (...MISMATCH: MismatchArgs, B>) => true toBeNever: (...MISMATCH: MismatchArgs, B>) => true @@ -109,42 +117,43 @@ export interface ExpectTypeOf { toBeSymbol: (...MISMATCH: MismatchArgs, B>) => true toBeNull: (...MISMATCH: MismatchArgs, B>) => true toBeUndefined: (...MISMATCH: MismatchArgs, B>) => true - toBeNullable: (...MISMATCH: MismatchArgs>>, B>) => true + toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true toMatchTypeOf: { (...MISMATCH: MismatchArgs, B>): true (expected: Expected, ...MISMATCH: MismatchArgs, B>): true } toEqualTypeOf: { - (...MISMATCH: MismatchArgs, B>): true - (expected: Expected, ...MISMATCH: MismatchArgs, B>): true + (...MISMATCH: MismatchArgs, B>): true + (expected: Expected, ...MISMATCH: MismatchArgs, B>): true } toBeCallableWith: B extends true ? (...args: Params) => true : never toBeConstructibleWith: B extends true ? (...args: ConstructorParams) => true : never toHaveProperty: ( key: K, ...MISMATCH: MismatchArgs, B> - ) => K extends keyof Actual ? ExpectTypeOf : true - extract: (v?: V) => ExpectTypeOf, B> - exclude: (v?: V) => ExpectTypeOf, B> - parameter: >(number: K) => ExpectTypeOf[K], B> - parameters: ExpectTypeOf, B> - constructorParameters: ExpectTypeOf, B> - thisParameter: ExpectTypeOf, B> - instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf : never - returns: Actual extends (...args: any[]) => infer R ? ExpectTypeOf : never - resolves: Actual extends PromiseLike ? ExpectTypeOf : never - items: Actual extends ArrayLike ? ExpectTypeOf : never - guards: Actual extends (v: any, ...args: any[]) => v is infer T ? ExpectTypeOf : never + ) => K extends keyof Actual ? ExpectTypeOf : true + extract: (v?: V) => ExpectTypeOf, B, Branded> + exclude: (v?: V) => ExpectTypeOf, B, Branded> + parameter: >(number: K) => ExpectTypeOf[K], B, Branded> + parameters: ExpectTypeOf, B, Branded> + constructorParameters: ExpectTypeOf, B, Branded> + thisParameter: ExpectTypeOf, B, Branded> + instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf : never + returns: Actual extends (...args: any[]) => infer R ? ExpectTypeOf : never + resolves: Actual extends PromiseLike ? ExpectTypeOf : never + items: Actual extends ArrayLike ? ExpectTypeOf : never + guards: Actual extends (v: any, ...args: any[]) => v is infer T ? ExpectTypeOf : never asserts: Actual extends (v: any, ...args: any[]) => asserts v is infer T ? // Guard methods `(v: any) => asserts v is T` does not actually defines a return type. Thus, any function taking 1 argument matches the signature before. // In case the inferred assertion type `R` could not be determined (so, `unknown`), consider the function as a non-guard, and return a `never` type. // See https://github.com/microsoft/TypeScript/issues/34636 unknown extends T ? never - : ExpectTypeOf + : ExpectTypeOf : never - not: ExpectTypeOf> -} + branded: Omit, 'branded'> + not: Omit, Branded>, 'branded'> + } const fn: any = () => true export type _ExpectTypeOf = { @@ -186,6 +195,7 @@ export const expectTypeOf: _ExpectTypeOf = (_actual?: Actual): ExpectTyp 'instance', 'guards', 'asserts', + 'branded', ] as const type Keys = keyof ExpectTypeOf diff --git a/test/errors.test.ts b/test/errors.test.ts index d2cc07eb..2d3910bc 100644 --- a/test/errors.test.ts +++ b/test/errors.test.ts @@ -18,9 +18,9 @@ test('toEqualTypeOf<...>() error message', async () => { 3 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " `) @@ -43,8 +43,8 @@ test('toMatchTypeOf<...>() error message', async () => { 3 expectTypeOf({a: 1}).toMatchTypeOf<{a: string}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:114:16 - 114 (...MISMATCH: MismatchArgs, B>): true + src/index.ts:122:16 + 122 (...MISMATCH: MismatchArgs, B>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " @@ -58,8 +58,8 @@ test('toMatchTypeOf(...) error message', async () => { 3 expectTypeOf({a: 1}).toMatchTypeOf({a: 'one'}) ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:115:36 - 115 (expected: Expected, ...MISMATCH: MismatchArgs, B>): true + src/index.ts:123:36 + 123 (expected: Expected, ...MISMATCH: MismatchArgs, B>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " @@ -86,17 +86,17 @@ test('usage test', () => { 21 expectTypeOf({a: 1, b: 1}).toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:35:25 - error TS2554: Expected 1 arguments, but got 0. 35 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:114:16 - 114 (...MISMATCH: MismatchArgs, B>): true + src/index.ts:122:16 + 122 (...MISMATCH: MismatchArgs, B>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:38:25 - error TS2554: Expected 1 arguments, but got 0. @@ -104,17 +104,17 @@ test('usage test', () => { 38 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:42:24 - error TS2554: Expected 2 arguments, but got 1. 42 expectTypeOf({a: 1}).toMatchTypeOf({b: 1}) ~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:115:36 - 115 (expected: Expected, ...MISMATCH: MismatchArgs, B>): true + src/index.ts:123:36 + 123 (expected: Expected, ...MISMATCH: MismatchArgs, B>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:51:25 - error TS2554: Expected 1 arguments, but got 0. @@ -122,8 +122,8 @@ test('usage test', () => { 51 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:114:16 - 114 (...MISMATCH: MismatchArgs, B>): true + src/index.ts:122:16 + 122 (...MISMATCH: MismatchArgs, B>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:52:25 - error TS2554: Expected 1 arguments, but got 0. @@ -131,17 +131,17 @@ test('usage test', () => { 52 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:61:25 - error TS2554: Expected 1 arguments, but got 0. 61 expectTypeOf().toBeNumber() ~~~~~~~~~~~~ - src/index.ts:105:16 - 105 toBeNumber: (...MISMATCH: MismatchArgs, B>) => true + src/index.ts:113:16 + 113 toBeNumber: (...MISMATCH: MismatchArgs, B>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:65:43 - error TS2554: Expected 1 arguments, but got 0. @@ -149,62 +149,62 @@ test('usage test', () => { 65 expectTypeOf<{deeply: {nested: any}}>().toEqualTypeOf<{deeply: {nested: unknown}}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:83:27 - error TS2554: Expected 1 arguments, but got 0. 83 expectTypeOf(undefined).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:112:18 - 112 toBeNullable: (...MISMATCH: MismatchArgs>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:120:18 + 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:87:22 - error TS2554: Expected 1 arguments, but got 0. 87 expectTypeOf(null).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:112:18 - 112 toBeNullable: (...MISMATCH: MismatchArgs>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:120:18 + 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:90:33 - error TS2554: Expected 1 arguments, but got 0. 90 expectTypeOf<1 | undefined>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:112:18 - 112 toBeNullable: (...MISMATCH: MismatchArgs>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:120:18 + 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:91:28 - error TS2554: Expected 1 arguments, but got 0. 91 expectTypeOf<1 | null>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:112:18 - 112 toBeNullable: (...MISMATCH: MismatchArgs>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:120:18 + 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:92:40 - error TS2554: Expected 1 arguments, but got 0. 92 expectTypeOf<1 | undefined | null>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:112:18 - 112 toBeNullable: (...MISMATCH: MismatchArgs>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:120:18 + 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:96:19 - error TS2554: Expected 1 arguments, but got 0. 96 expectTypeOf(1).toBeUnknown() ~~~~~~~~~~~~~ - src/index.ts:100:17 - 100 toBeUnknown: (...MISMATCH: MismatchArgs, B>) => true + src/index.ts:108:17 + 108 toBeUnknown: (...MISMATCH: MismatchArgs, B>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:97:19 - error TS2554: Expected 1 arguments, but got 0. @@ -212,17 +212,17 @@ test('usage test', () => { 97 expectTypeOf(1).toBeAny() ~~~~~~~~~ - src/index.ts:99:13 - 99 toBeAny: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:107:13 + 107 toBeAny: (...MISMATCH: MismatchArgs, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:98:19 - error TS2554: Expected 1 arguments, but got 0. 98 expectTypeOf(1).toBeNever() ~~~~~~~~~~~ - src/index.ts:101:15 - 101 toBeNever: (...MISMATCH: MismatchArgs, B>) => true + src/index.ts:109:15 + 109 toBeNever: (...MISMATCH: MismatchArgs, B>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:99:19 - error TS2554: Expected 1 arguments, but got 0. @@ -230,8 +230,8 @@ test('usage test', () => { 99 expectTypeOf(1).toBeNull() ~~~~~~~~~~ - src/index.ts:110:14 - 110 toBeNull: (...MISMATCH: MismatchArgs, B>) => true + src/index.ts:118:14 + 118 toBeNull: (...MISMATCH: MismatchArgs, B>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:100:19 - error TS2554: Expected 1 arguments, but got 0. @@ -239,8 +239,8 @@ test('usage test', () => { 100 expectTypeOf(1).toBeUndefined() ~~~~~~~~~~~~~~~ - src/index.ts:111:19 - 111 toBeUndefined: (...MISMATCH: MismatchArgs, B>) => true + src/index.ts:119:19 + 119 toBeUndefined: (...MISMATCH: MismatchArgs, B>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:101:19 - error TS2554: Expected 1 arguments, but got 0. @@ -248,17 +248,17 @@ test('usage test', () => { 101 expectTypeOf(1).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:112:18 - 112 toBeNullable: (...MISMATCH: MismatchArgs>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:120:18 + 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:106:35 - error TS2554: Expected 1 arguments, but got 0. 106 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:114:16 - 114 (...MISMATCH: MismatchArgs, B>): true + src/index.ts:122:16 + 122 (...MISMATCH: MismatchArgs, B>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:130:71 - error TS2554: Expected 2 arguments, but got 1. @@ -266,8 +266,8 @@ test('usage test', () => { 130 expectTypeOf>().exclude().toHaveProperty('xxl') ~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:125:5 - 125 ...MISMATCH: MismatchArgs, B> + src/index.ts:133:5 + 133 ...MISMATCH: MismatchArgs, B> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:147:21 - error TS2554: Expected 2 arguments, but got 1. @@ -275,8 +275,8 @@ test('usage test', () => { 147 expectTypeOf(obj).toHaveProperty('c') ~~~~~~~~~~~~~~~~~~~ - src/index.ts:125:5 - 125 ...MISMATCH: MismatchArgs, B> + src/index.ts:133:5 + 133 ...MISMATCH: MismatchArgs, B> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:152:41 - error TS2554: Expected 1 arguments, but got 0. @@ -284,8 +284,8 @@ test('usage test', () => { 152 expectTypeOf(obj).toHaveProperty('a').toBeString() ~~~~~~~~~~~~ - src/index.ts:106:16 - 106 toBeString: (...MISMATCH: MismatchArgs, B>) => true + src/index.ts:114:16 + 114 toBeString: (...MISMATCH: MismatchArgs, B>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:159:27 - error TS2554: Expected 1 arguments, but got 0. @@ -293,27 +293,27 @@ test('usage test', () => { 159 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:179:19 - error TS2554: Expected 1 arguments, but got 0. 179 expectTypeOf(f).toBeAny() ~~~~~~~~~ - src/index.ts:99:13 - 99 toBeAny: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:107:13 + 107 toBeAny: (...MISMATCH: MismatchArgs, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:180:27 - error TS2554: Expected 1 arguments, but got 0. 180 expectTypeOf(f).returns.toBeAny() ~~~~~~~~~ - src/index.ts:99:13 - 99 toBeAny: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:107:13 + 107 toBeAny: (...MISMATCH: MismatchArgs, B>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:183:46 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'. @@ -328,8 +328,8 @@ test('usage test', () => { 246 expectTypeOf([1, 2, 3]).items.toBeString() ~~~~~~~~~~~~ - src/index.ts:106:16 - 106 toBeString: (...MISMATCH: MismatchArgs, B>) => true + src/index.ts:114:16 + 114 toBeString: (...MISMATCH: MismatchArgs, B>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:258:31 - error TS2554: Expected 1 arguments, but got 0. @@ -337,63 +337,81 @@ test('usage test', () => { 258 expectTypeOf<{a: string}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Arguments for the rest parameter 'MISMATCH' were not provided. + test/usage.test.ts:262:32 - error TS2554: Expected 1 arguments, but got 0. + + 262 expectTypeOf<{a?: number}>().toEqualTypeOf<{}>() + ~~~~~~~~~~~~~~~~~~~ + + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:263:32 - error TS2554: Expected 1 arguments, but got 0. 263 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:264:32 - error TS2554: Expected 1 arguments, but got 0. 264 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number | undefined}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:265:39 - error TS2554: Expected 1 arguments, but got 0. 265 expectTypeOf<{a?: number | null}>().toEqualTypeOf<{a: number | null}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Arguments for the rest parameter 'MISMATCH' were not provided. + test/usage.test.ts:266:37 - error TS2554: Expected 1 arguments, but got 0. + + 266 expectTypeOf<{a: {b?: number}}>().toEqualTypeOf<{a: {}}>() + ~~~~~~~~~~~~~~~~~~~~~~~~ + + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:274:22 - error TS2554: Expected 1 arguments, but got 0. 274 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:280:22 - error TS2554: Expected 1 arguments, but got 0. 280 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:297:28 - error TS2554: Expected 1 arguments, but got 0. 297 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:118:16 - 118 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, B>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " `) diff --git a/test/types.test.ts b/test/types.test.ts index 9e69af1c..cba2e7a7 100644 --- a/test/types.test.ts +++ b/test/types.test.ts @@ -189,3 +189,447 @@ test(`undefined isn't removed from unions`, () => { expectTypeOf().toEqualTypeOf() expectTypeOf().toMatchTypeOf() }) + +test('Distinguish between functions whose return types differ by readonly prop', () => { + type ObjWithReadonlyProp = {readonly x: number} + type ObjWithoutReadonlyProp = {x: number} + + function original(o: ObjWithReadonlyProp): ObjWithReadonlyProp { + return o + } + + function same(o: ObjWithReadonlyProp): ObjWithReadonlyProp { + return o + } + + function different(o: ObjWithoutReadonlyProp): ObjWithoutReadonlyProp { + return o + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf(original).branded.toEqualTypeOf(original) + expectTypeOf().toEqualTypeOf() + expectTypeOf(different).toEqualTypeOf(different) + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf(original).not.toEqualTypeOf(original) + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf(different).not.toEqualTypeOf(different) + + // Same shape + expectTypeOf().toEqualTypeOf() + expectTypeOf(original).toEqualTypeOf(same) + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf(original).not.toEqualTypeOf(same) + + // Different presence of readonly prop + expectTypeOf().not.toEqualTypeOf() + expectTypeOf(original).not.toEqualTypeOf(different) + // @ts-expect-error + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf(original).toEqualTypeOf(different) +}) + +test('Distinguish between classes with only private properties', () => { + class Original { + // eslint-disable-next-line mmkal/@typescript-eslint/class-literal-property-style + private readonly prop = 1 + } + + class Different { + // eslint-disable-next-line mmkal/@typescript-eslint/class-literal-property-style + private readonly prop = 1 + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf(Original).toEqualTypeOf(Original) + expectTypeOf().toEqualTypeOf() + expectTypeOf(Different).toEqualTypeOf(Different) + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf(Original).not.toEqualTypeOf(Original) + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf(Different).not.toEqualTypeOf(Different) + + // Different classes + expectTypeOf().not.toEqualTypeOf() + expectTypeOf(Original).not.toEqualTypeOf(Different) + // @ts-expect-error + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf(Original).toEqualTypeOf(Different) +}) + +test('Distinguish between types with generics used in type assertion', () => { + interface Guard { + // eslint-disable-next-line mmkal/@typescript-eslint/prefer-function-type + (arg: unknown): arg is T + } + + // Self-identity + expectTypeOf>().toEqualTypeOf>() + // @ts-expect-error + expectTypeOf>().not.toEqualTypeOf>() + + // Different return types + expectTypeOf>().not.toEqualTypeOf>() + // @ts-expect-error + expectTypeOf>().toEqualTypeOf>() +}) + +test('Distinguish between functions with generics vs unknown', () => { + function funcWithGenerics(p1: T, p2: T): T { + return p1 || p2 + } + + function funcWithUnknown(p1: unknown, p2: unknown): unknown { + return p1 || p2 + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf(funcWithGenerics).toEqualTypeOf(funcWithGenerics) + expectTypeOf().toEqualTypeOf() + expectTypeOf(funcWithUnknown).toEqualTypeOf(funcWithUnknown) + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf(funcWithGenerics).not.toEqualTypeOf(funcWithGenerics) + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf(funcWithUnknown).not.toEqualTypeOf(funcWithUnknown) + + // Generic vs unknown with otherwise same shape + expectTypeOf().not.toEqualTypeOf() + expectTypeOf(funcWithGenerics).not.toEqualTypeOf(funcWithUnknown) + // @ts-expect-error + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf(funcWithGenerics).toEqualTypeOf(funcWithUnknown) +}) + +interface BaseFunc { + // eslint-disable-next-line mmkal/@typescript-eslint/prefer-function-type + (str: string): number +} + +test('Distinguish between functions with readonly properties', () => { + interface Original extends BaseFunc { + readonly prop: string + } + + interface Same extends BaseFunc { + readonly prop: string + } + + interface Different extends BaseFunc { + prop: string + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Only one readonly otherwise same shape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +test('Distinguish between functions with optional properties', () => { + interface Original extends BaseFunc { + prop?: number + } + + interface Same extends BaseFunc { + prop?: number + } + + interface Different extends BaseFunc { + prop: number | undefined + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Only one optional otherwise same shape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +test('Distinguish between functions with properties of different types', () => { + interface Original extends BaseFunc { + prop: number + } + + interface Same extends BaseFunc { + prop: number + } + + interface Different extends BaseFunc { + prop: string + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Only one optional otherwise same shape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +interface BaseConstructor { + // eslint-disable-next-line mmkal/@typescript-eslint/prefer-function-type + new (str: string): {someProp: number} +} + +test('Distinguish between constructors with readonly properties', () => { + interface Original extends BaseConstructor { + readonly prop: string + } + + interface Same extends BaseConstructor { + readonly prop: string + } + + interface Different extends BaseConstructor { + prop: string + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Only one readonly otherwise same shape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +test('Distinguish between constructors with optional properties', () => { + interface Original extends BaseConstructor { + prop?: number + } + + interface Same extends BaseConstructor { + prop?: number + } + + interface Different extends BaseConstructor { + prop: number | undefined + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Only one optional otherwise same shape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +test('Distinguish between constructors with properties of different types', () => { + interface Original extends BaseConstructor { + prop: number + } + + interface Same extends BaseConstructor { + prop: number + } + + interface Different extends BaseConstructor { + prop: string + } + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Only one optional otherwise same shape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +test('Distinguish between tuples with differing item type', () => { + type Original = [{prop: number}] + type Same = [{prop: number}] + type Different = [{readonly prop: number}] + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // One item type property readonly otherwise same sape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +test('Distinguish between array with properties', () => { + type Original = number[] & {readonly prop: number} + type Same = number[] & {readonly prop: number} + type Different = number[] & {prop: number} + + // Self-identity + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // Same shape + expectTypeOf().toEqualTypeOf() + // @ts-expect-error + expectTypeOf().not.toEqualTypeOf() + + // One item type property readonly otherwise same sape + expectTypeOf().not.toEqualTypeOf() + // @ts-expect-error + expectTypeOf().toEqualTypeOf() +}) + +test('Distinguish between different types that are OR`d together', () => { + expectTypeOf<{foo: number} | {bar: string}>().toEqualTypeOf<{foo: number} | {bar: string}>() + // @ts-expect-error + expectTypeOf<{foo: number} | {bar: string}>().not.toEqualTypeOf<{foo: number} | {bar: string}>() + + expectTypeOf<{foo: number} | {bar: string}>().not.toEqualTypeOf<{foo: number}>() + // @ts-expect-error + expectTypeOf<{foo: number} | {bar: string}>().toEqualTypeOf<{foo: number}>() +}) + +test('Distinguish between identical types that are OR`d together', () => { + expectTypeOf<{foo: number} | {foo: number}>().toEqualTypeOf<{foo: number} | {foo: number}>() + // Note: The `| T` in `Equal` in index.ts makes this work. + expectTypeOf<{foo: number} | {foo: number}>().toEqualTypeOf<{foo: number}>() + // @ts-expect-error + expectTypeOf<{foo: number} | {foo: number}>().not.toEqualTypeOf<{foo: number} | {foo: number}>() + // @ts-expect-error + expectTypeOf<{foo: number} | {foo: number}>().not.toEqualTypeOf<{foo: number}>() +}) + +test('Distinguish between different types that are AND`d together', () => { + // Identity + expectTypeOf<{foo: number} & {bar: string}>().toEqualTypeOf<{foo: number} & {bar: string}>() + // @ts-expect-error + expectTypeOf<{foo: number} & {bar: string}>().not.toEqualTypeOf<{foo: number} & {bar: string}>() + + // Two types intersect to an equivalent non-intersected type + // This is broken at the moment. See the next test + // expectTypeOf<{foo: number} & {bar: string}>().toEqualTypeOf<{foo: number; bar: string}>() + // expectTypeOf<{foo: number} & {bar: string}>().not.toEqualTypeOf<{foo: number; bar: string}>() +}) + +test('Works arounds tsc bug not handling intersected types for this form of equivalence', () => { + // @ts-expect-error This is the bug. + expectTypeOf<{foo: number} & {bar: string}>().toEqualTypeOf<{foo: number; bar: string}>() + // This should \@ts-expect-error but does not. + expectTypeOf<{foo: number} & {bar: string}>().not.toEqualTypeOf<{foo: number; bar: string}>() + + const one: {foo: number} & {bar: string} = {foo: 1, bar: 'a'} + const two: {foo: number; bar: string} = {foo: 1, bar: 'a'} + // @ts-expect-error It also repros with variables and their inferred types + expectTypeOf(one).toEqualTypeOf(two) + // This should \@ts-expect-error but does not. + expectTypeOf(one).not.toEqualTypeOf(two) + + // The workaround is the new optional .branded modifier. + expectTypeOf<{foo: number} & {bar: string}>().branded.toEqualTypeOf<{foo: number; bar: string}>() + expectTypeOf(one).branded.toEqualTypeOf(two) + // @ts-expect-error + expectTypeOf<{foo: number} & {bar: string}>().branded.not.toEqualTypeOf<{foo: number; bar: string}>() + // @ts-expect-error + expectTypeOf(one).branded.not.toEqualTypeOf(two) +}) + +test('Distinguish between identical types that are AND`d together', () => { + expectTypeOf<{foo: number} & {foo: number}>().toEqualTypeOf<{foo: number} & {foo: number}>() + // Note: The `& T` in `Equal` in index.ts makes this work. + expectTypeOf<{foo: number} & {foo: number}>().toEqualTypeOf<{foo: number}>() + // @ts-expect-error + expectTypeOf<{foo: number} & {foo: number}>().not.toEqualTypeOf<{foo: number} & {foo: number}>() + // @ts-expect-error + expectTypeOf<{foo: number} & {foo: number}>().not.toEqualTypeOf<{foo: number}>() +}) From 8944ede5e2def5a4cefb0accaa993d9079f7bfe3 Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Thu, 13 Apr 2023 13:38:06 -0400 Subject: [PATCH 2/7] Use options bag --- src/index.ts | 90 +++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/index.ts b/src/index.ts index f9733022..1dc0cc91 100644 --- a/src/index.ts +++ b/src/index.ts @@ -101,64 +101,68 @@ export type ConstructorParams = Actual extends new (...args: infer P) => : P : never -type MismatchArgs = Eq extends true ? [] : [never] - -export interface ExpectTypeOf { - toBeAny: (...MISMATCH: MismatchArgs, B>) => true - toBeUnknown: (...MISMATCH: MismatchArgs, B>) => true - toBeNever: (...MISMATCH: MismatchArgs, B>) => true - toBeFunction: (...MISMATCH: MismatchArgs any>, B>) => true - toBeObject: (...MISMATCH: MismatchArgs, B>) => true - toBeArray: (...MISMATCH: MismatchArgs, B>) => true - toBeNumber: (...MISMATCH: MismatchArgs, B>) => true - toBeString: (...MISMATCH: MismatchArgs, B>) => true - toBeBoolean: (...MISMATCH: MismatchArgs, B>) => true - toBeVoid: (...MISMATCH: MismatchArgs, B>) => true - toBeSymbol: (...MISMATCH: MismatchArgs, B>) => true - toBeNull: (...MISMATCH: MismatchArgs, B>) => true - toBeUndefined: (...MISMATCH: MismatchArgs, B>) => true - toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true +type MismatchArgs = Eq extends true ? [] : [never] + +export interface ExpectTypeOfOptions { + positive: boolean + branded: boolean +} +export interface ExpectTypeOf { + toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeUnknown: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeNever: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeFunction: (...MISMATCH: MismatchArgs any>, Options['positive']>) => true + toBeObject: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeArray: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeNumber: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeBoolean: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeVoid: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeSymbol: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeNull: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeUndefined: (...MISMATCH: MismatchArgs, Options['positive']>) => true + toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true toMatchTypeOf: { - (...MISMATCH: MismatchArgs, B>): true - (expected: Expected, ...MISMATCH: MismatchArgs, B>): true + (...MISMATCH: MismatchArgs, Options['positive']>): true + (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true } toEqualTypeOf: { - (...MISMATCH: MismatchArgs, B>): true - (expected: Expected, ...MISMATCH: MismatchArgs, B>): true + (...MISMATCH: MismatchArgs, Options['positive']>): true + (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true } - toBeCallableWith: B extends true ? (...args: Params) => true : never - toBeConstructibleWith: B extends true ? (...args: ConstructorParams) => true : never + toBeCallableWith: Options['positive'] extends true ? (...args: Params) => true : never + toBeConstructibleWith: Options['positive'] extends true ? (...args: ConstructorParams) => true : never toHaveProperty: ( key: K, - ...MISMATCH: MismatchArgs, B> - ) => K extends keyof Actual ? ExpectTypeOf : true - extract: (v?: V) => ExpectTypeOf, B, Branded> - exclude: (v?: V) => ExpectTypeOf, B, Branded> - parameter: >(number: K) => ExpectTypeOf[K], B, Branded> - parameters: ExpectTypeOf, B, Branded> - constructorParameters: ExpectTypeOf, B, Branded> - thisParameter: ExpectTypeOf, B, Branded> - instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf : never - returns: Actual extends (...args: any[]) => infer R ? ExpectTypeOf : never - resolves: Actual extends PromiseLike ? ExpectTypeOf : never - items: Actual extends ArrayLike ? ExpectTypeOf : never - guards: Actual extends (v: any, ...args: any[]) => v is infer T ? ExpectTypeOf : never + ...MISMATCH: MismatchArgs, Options['positive']> + ) => K extends keyof Actual ? ExpectTypeOf : true + extract: (v?: V) => ExpectTypeOf, Options> + exclude: (v?: V) => ExpectTypeOf, Options> + parameter: >(number: K) => ExpectTypeOf[K], Options> + parameters: ExpectTypeOf, Options> + constructorParameters: ExpectTypeOf, Options> + thisParameter: ExpectTypeOf, Options> + instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf : never + returns: Actual extends (...args: any[]) => infer R ? ExpectTypeOf : never + resolves: Actual extends PromiseLike ? ExpectTypeOf : never + items: Actual extends ArrayLike ? ExpectTypeOf : never + guards: Actual extends (v: any, ...args: any[]) => v is infer T ? ExpectTypeOf : never asserts: Actual extends (v: any, ...args: any[]) => asserts v is infer T ? // Guard methods `(v: any) => asserts v is T` does not actually defines a return type. Thus, any function taking 1 argument matches the signature before. // In case the inferred assertion type `R` could not be determined (so, `unknown`), consider the function as a non-guard, and return a `never` type. // See https://github.com/microsoft/TypeScript/issues/34636 unknown extends T ? never - : ExpectTypeOf + : ExpectTypeOf : never - branded: Omit, 'branded'> - not: Omit, Branded>, 'branded'> + branded: Omit, 'branded'> + not: Omit; branded: Options['branded']}>, 'not'> } const fn: any = () => true export type _ExpectTypeOf = { - (actual: Actual): ExpectTypeOf - (): ExpectTypeOf + (actual: Actual): ExpectTypeOf + (): ExpectTypeOf } /** @@ -183,7 +187,7 @@ export type _ExpectTypeOf = { * @description * See the [full docs](https://npmjs.com/package/expect-type#documentation) for lots more examples. */ -export const expectTypeOf: _ExpectTypeOf = (_actual?: Actual): ExpectTypeOf => { +export const expectTypeOf: _ExpectTypeOf = (_actual?: Actual): ExpectTypeOf => { const nonFunctionProperties = [ 'parameters', 'returns', @@ -230,5 +234,5 @@ export const expectTypeOf: _ExpectTypeOf = (_actual?: Actual): ExpectTyp const getterProperties: readonly Keys[] = nonFunctionProperties getterProperties.forEach((prop: Keys) => Object.defineProperty(obj, prop, {get: () => expectTypeOf({})})) - return obj as ExpectTypeOf + return obj as ExpectTypeOf } From bd7275a58222791af20b76c042fef3a5b09dc340 Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Thu, 13 Apr 2023 13:38:10 -0400 Subject: [PATCH 3/7] ts-expect-errors --- test/types.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/types.test.ts b/test/types.test.ts index 8d5c2ce7..23e33fd6 100644 --- a/test/types.test.ts +++ b/test/types.test.ts @@ -71,8 +71,10 @@ test(`never types don't sneak by`, () => { }) test('intersections work properly', () => { + // @ts-expect-error limitation of new implementation expectTypeOf<{a: 1} & {b: 2}>().toEqualTypeOf<{a: 1; b: 2}>() expectTypeOf<{a: 1} & {b: 2}>().toMatchTypeOf<{a: 1; b: 2}>() + // @ts-expect-error limitation of new implementation expectTypeOf<{a: 1; b: 2}>().toEqualTypeOf<{a: 1} & {b: 2}>() expectTypeOf<{a: 1; b: 2}>().toMatchTypeOf<{a: 1} & {b: 2}>() }) From 3081e2edc300d6c3fe1e954617ac4ac21d0d48fc Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Thu, 13 Apr 2023 13:48:37 -0400 Subject: [PATCH 4/7] update line numbers in snapshots --- test/errors.test.ts | 234 ++++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/test/errors.test.ts b/test/errors.test.ts index 2d3910bc..2723873b 100644 --- a/test/errors.test.ts +++ b/test/errors.test.ts @@ -18,9 +18,9 @@ test('toEqualTypeOf<...>() error message', async () => { 3 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " `) @@ -43,9 +43,9 @@ test('toMatchTypeOf<...>() error message', async () => { 3 expectTypeOf({a: 1}).toMatchTypeOf<{a: string}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:122:16 - 122 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " `) @@ -58,9 +58,9 @@ test('toMatchTypeOf(...) error message', async () => { 3 expectTypeOf({a: 1}).toMatchTypeOf({a: 'one'}) ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:123:36 - 123 (expected: Expected, ...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:127:36 + 127 (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " `) @@ -86,234 +86,234 @@ test('usage test', () => { 21 expectTypeOf({a: 1, b: 1}).toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:35:25 - error TS2554: Expected 1 arguments, but got 0. 35 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:122:16 - 122 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:38:25 - error TS2554: Expected 1 arguments, but got 0. 38 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:42:24 - error TS2554: Expected 2 arguments, but got 1. 42 expectTypeOf({a: 1}).toMatchTypeOf({b: 1}) ~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:123:36 - 123 (expected: Expected, ...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:127:36 + 127 (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:51:25 - error TS2554: Expected 1 arguments, but got 0. 51 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:122:16 - 122 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:52:25 - error TS2554: Expected 1 arguments, but got 0. 52 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:61:25 - error TS2554: Expected 1 arguments, but got 0. 61 expectTypeOf().toBeNumber() ~~~~~~~~~~~~ - src/index.ts:113:16 - 113 toBeNumber: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:117:16 + 117 toBeNumber: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:65:43 - error TS2554: Expected 1 arguments, but got 0. 65 expectTypeOf<{deeply: {nested: any}}>().toEqualTypeOf<{deeply: {nested: unknown}}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:83:27 - error TS2554: Expected 1 arguments, but got 0. 83 expectTypeOf(undefined).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:120:18 - 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:124:18 + 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:87:22 - error TS2554: Expected 1 arguments, but got 0. 87 expectTypeOf(null).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:120:18 - 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:124:18 + 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:90:33 - error TS2554: Expected 1 arguments, but got 0. 90 expectTypeOf<1 | undefined>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:120:18 - 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:124:18 + 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:91:28 - error TS2554: Expected 1 arguments, but got 0. 91 expectTypeOf<1 | null>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:120:18 - 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:124:18 + 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:92:40 - error TS2554: Expected 1 arguments, but got 0. 92 expectTypeOf<1 | undefined | null>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:120:18 - 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:124:18 + 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:96:19 - error TS2554: Expected 1 arguments, but got 0. 96 expectTypeOf(1).toBeUnknown() ~~~~~~~~~~~~~ - src/index.ts:108:17 - 108 toBeUnknown: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:112:17 + 112 toBeUnknown: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:97:19 - error TS2554: Expected 1 arguments, but got 0. 97 expectTypeOf(1).toBeAny() ~~~~~~~~~ - src/index.ts:107:13 - 107 toBeAny: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:111:13 + 111 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:98:19 - error TS2554: Expected 1 arguments, but got 0. 98 expectTypeOf(1).toBeNever() ~~~~~~~~~~~ - src/index.ts:109:15 - 109 toBeNever: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:113:15 + 113 toBeNever: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:99:19 - error TS2554: Expected 1 arguments, but got 0. 99 expectTypeOf(1).toBeNull() ~~~~~~~~~~ - src/index.ts:118:14 - 118 toBeNull: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:122:14 + 122 toBeNull: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:100:19 - error TS2554: Expected 1 arguments, but got 0. 100 expectTypeOf(1).toBeUndefined() ~~~~~~~~~~~~~~~ - src/index.ts:119:19 - 119 toBeUndefined: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:123:19 + 123 toBeUndefined: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:101:19 - error TS2554: Expected 1 arguments, but got 0. 101 expectTypeOf(1).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:120:18 - 120 toBeNullable: (...MISMATCH: MismatchArgs, Branded>>, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:124:18 + 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:106:35 - error TS2554: Expected 1 arguments, but got 0. 106 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:122:16 - 122 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:126:16 + 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:130:71 - error TS2554: Expected 2 arguments, but got 1. 130 expectTypeOf>().exclude().toHaveProperty('xxl') ~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:133:5 - 133 ...MISMATCH: MismatchArgs, B> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:137:5 + 137 ...MISMATCH: MismatchArgs, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:147:21 - error TS2554: Expected 2 arguments, but got 1. 147 expectTypeOf(obj).toHaveProperty('c') ~~~~~~~~~~~~~~~~~~~ - src/index.ts:133:5 - 133 ...MISMATCH: MismatchArgs, B> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:137:5 + 137 ...MISMATCH: MismatchArgs, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:152:41 - error TS2554: Expected 1 arguments, but got 0. 152 expectTypeOf(obj).toHaveProperty('a').toBeString() ~~~~~~~~~~~~ - src/index.ts:114:16 - 114 toBeString: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:118:16 + 118 toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:159:27 - error TS2554: Expected 1 arguments, but got 0. 159 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:179:19 - error TS2554: Expected 1 arguments, but got 0. 179 expectTypeOf(f).toBeAny() ~~~~~~~~~ - src/index.ts:107:13 - 107 toBeAny: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:111:13 + 111 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:180:27 - error TS2554: Expected 1 arguments, but got 0. 180 expectTypeOf(f).returns.toBeAny() ~~~~~~~~~ - src/index.ts:107:13 - 107 toBeAny: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:111:13 + 111 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:183:46 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'. @@ -328,90 +328,90 @@ test('usage test', () => { 246 expectTypeOf([1, 2, 3]).items.toBeString() ~~~~~~~~~~~~ - src/index.ts:114:16 - 114 toBeString: (...MISMATCH: MismatchArgs, B>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:118:16 + 118 toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:258:31 - error TS2554: Expected 1 arguments, but got 0. 258 expectTypeOf<{a: string}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:262:32 - error TS2554: Expected 1 arguments, but got 0. 262 expectTypeOf<{a?: number}>().toEqualTypeOf<{}>() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:263:32 - error TS2554: Expected 1 arguments, but got 0. 263 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:264:32 - error TS2554: Expected 1 arguments, but got 0. 264 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number | undefined}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:265:39 - error TS2554: Expected 1 arguments, but got 0. 265 expectTypeOf<{a?: number | null}>().toEqualTypeOf<{a: number | null}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:266:37 - error TS2554: Expected 1 arguments, but got 0. 266 expectTypeOf<{a: {b?: number}}>().toEqualTypeOf<{a: {}}>() ~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:274:22 - error TS2554: Expected 1 arguments, but got 0. 274 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:280:22 - error TS2554: Expected 1 arguments, but got 0. 280 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:297:28 - error TS2554: Expected 1 arguments, but got 0. 297 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, B>): true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " `) From 5d5b1eba988a49e99547c307bb325f4e30f4711d Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Tue, 9 May 2023 23:31:33 -0400 Subject: [PATCH 5/7] Add test for #29 --- test/usage.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/usage.test.ts b/test/usage.test.ts index e1c0e6fe..8d189816 100644 --- a/test/usage.test.ts +++ b/test/usage.test.ts @@ -246,6 +246,10 @@ test('Array items can be checked with `.items`', () => { expectTypeOf([1, 2, 3]).items.not.toBeString() }) +test('You can also compare arrays directly', () => { + expectTypeOf().not.toEqualTypeOf() +}) + test('Check that functions never return', () => { const thrower = () => { throw new Error('oh no') From f4dab98cda34f5c28e81a827a64f6f59f478f03d Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Tue, 9 May 2023 23:42:25 -0400 Subject: [PATCH 6/7] add to readme, update snapshots --- README.md | 22 ++++++++++++++++++ test/errors.test.ts | 54 ++++++++++++++++++++++++++++++--------------- test/types.test.ts | 6 ++--- test/usage.test.ts | 12 ++++++++++ 4 files changed, 73 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index f2bb1b16..66c47ca8 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,12 @@ expectTypeOf([1, 2, 3]).items.toBeNumber() expectTypeOf([1, 2, 3]).items.not.toBeString() ``` +You can also compare arrays directly: + +```typescript +expectTypeOf().not.toEqualTypeOf() +``` + Check that functions never return: ```typescript @@ -420,6 +426,22 @@ class C { expectTypeOf().toEqualTypeOf() ``` + +Known limitation: Intersection types can cause issues with `toEqualTypeOf`: + +```typescript +// @ts-expect-error the following line doesn't compile, even though the types are arguably the same. +// See https://github.com/mmkal/expect-type/pull/21 +expectTypeOf<{a: 1} & {b: 2}>().toEqualTypeOf<{a: 1; b: 2}>() +``` + +To workaround, you can use a mapped type: + +```typescript +type Simplify = {[K in keyof T]: T[K]} + +expectTypeOf>().toEqualTypeOf<{a: 1; b: 2}>() +``` ### Within test frameworks diff --git a/test/errors.test.ts b/test/errors.test.ts index 2723873b..4fd1261f 100644 --- a/test/errors.test.ts +++ b/test/errors.test.ts @@ -332,83 +332,101 @@ test('usage test', () => { 118 toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:258:31 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:250:25 - error TS2554: Expected 1 arguments, but got 0. - 258 expectTypeOf<{a: string}>().toEqualTypeOf<{a: number}>() + 250 expectTypeOf().toEqualTypeOf() + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Arguments for the rest parameter 'MISMATCH' were not provided. + test/usage.test.ts:262:31 - error TS2554: Expected 1 arguments, but got 0. + + 262 expectTypeOf<{a: string}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:262:32 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:266:32 - error TS2554: Expected 1 arguments, but got 0. - 262 expectTypeOf<{a?: number}>().toEqualTypeOf<{}>() + 266 expectTypeOf<{a?: number}>().toEqualTypeOf<{}>() ~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:263:32 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:267:32 - error TS2554: Expected 1 arguments, but got 0. - 263 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number}>() + 267 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:264:32 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:268:32 - error TS2554: Expected 1 arguments, but got 0. - 264 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number | undefined}>() + 268 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number | undefined}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:265:39 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:269:39 - error TS2554: Expected 1 arguments, but got 0. - 265 expectTypeOf<{a?: number | null}>().toEqualTypeOf<{a: number | null}>() + 269 expectTypeOf<{a?: number | null}>().toEqualTypeOf<{a: number | null}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:266:37 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:270:37 - error TS2554: Expected 1 arguments, but got 0. - 266 expectTypeOf<{a: {b?: number}}>().toEqualTypeOf<{a: {}}>() + 270 expectTypeOf<{a: {b?: number}}>().toEqualTypeOf<{a: {}}>() ~~~~~~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:274:22 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:278:22 - error TS2554: Expected 1 arguments, but got 0. - 274 expectTypeOf().toEqualTypeOf() + 278 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:280:22 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:284:22 - error TS2554: Expected 1 arguments, but got 0. - 280 expectTypeOf().toEqualTypeOf() + 284 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. - test/usage.test.ts:297:28 - error TS2554: Expected 1 arguments, but got 0. + test/usage.test.ts:301:28 - error TS2554: Expected 1 arguments, but got 0. - 297 expectTypeOf().toEqualTypeOf() + 301 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 + 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Arguments for the rest parameter 'MISMATCH' were not provided. + test/usage.test.ts:316:35 - error TS2554: Expected 1 arguments, but got 0. + + 316 expectTypeOf<{a: 1} & {b: 2}>().toEqualTypeOf<{a: 1; b: 2}>() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:130:16 130 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/test/types.test.ts b/test/types.test.ts index 9825678a..2e57ed4f 100644 --- a/test/types.test.ts +++ b/test/types.test.ts @@ -70,11 +70,11 @@ test(`never types don't sneak by`, () => { expectTypeOf().toMatchTypeOf<{foo: string}>() }) -test('intersections work properly', () => { - // @ts-expect-error limitation of new implementation +test('intersections do not currently work properly', () => { + // @ts-expect-error limitation of new implementation https://github.com/mmkal/expect-type/pull/21 expectTypeOf<{a: 1} & {b: 2}>().toEqualTypeOf<{a: 1; b: 2}>() expectTypeOf<{a: 1} & {b: 2}>().toMatchTypeOf<{a: 1; b: 2}>() - // @ts-expect-error limitation of new implementation + // @ts-expect-error limitation of new implementation https://github.com/mmkal/expect-type/pull/21 expectTypeOf<{a: 1; b: 2}>().toEqualTypeOf<{a: 1} & {b: 2}>() expectTypeOf<{a: 1; b: 2}>().toMatchTypeOf<{a: 1} & {b: 2}>() }) diff --git a/test/usage.test.ts b/test/usage.test.ts index 8d189816..950fd303 100644 --- a/test/usage.test.ts +++ b/test/usage.test.ts @@ -309,3 +309,15 @@ test('Distinguish between classes with different constructors', () => { expectTypeOf().toEqualTypeOf() }) + +test('Known limitation: Intersection types can cause issues with `toEqualTypeOf`', () => { + // @ts-expect-error the following line doesn't compile, even though the types are arguably the same. + // See https://github.com/mmkal/expect-type/pull/21 + expectTypeOf<{a: 1} & {b: 2}>().toEqualTypeOf<{a: 1; b: 2}>() +}) + +test('To workaround, you can use a mapped type', () => { + type Simplify = {[K in keyof T]: T[K]} + + expectTypeOf>().toEqualTypeOf<{a: 1; b: 2}>() +}) From 241e1e57ffa2e5f09822837f648ffb3bb9d4fabf Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Tue, 9 May 2023 23:44:14 -0400 Subject: [PATCH 7/7] prettier? --- src/index.ts | 42 +++++++---- test/errors.test.ts | 176 ++++++++++++++++++++++---------------------- 2 files changed, 116 insertions(+), 102 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1dc0cc91..ded80201 100644 --- a/src/index.ts +++ b/src/index.ts @@ -84,15 +84,17 @@ type ReadonlyEquivalent = Extends< export type Extends = IsNever extends true ? IsNever : [L] extends [R] ? true : false export type StrictExtends = Extends, DeepBrand> -type StrictEqual = - (() => T extends (L & T) | T ? true : false) extends - (() => T extends (R & T) | T ? true : false) ? - IsNever extends IsNever ? true : false : false - -export type Equal = - Branded extends true - ? And<[StrictExtends, StrictExtends]> - : StrictEqual +type StrictEqual = (() => T extends (L & T) | T ? true : false) extends () => T extends (R & T) | T + ? true + : false + ? IsNever extends IsNever + ? true + : false + : false + +export type Equal = Branded extends true + ? And<[StrictExtends, StrictExtends]> + : StrictEqual export type Params = Actual extends (...args: infer P) => any ? P : never export type ConstructorParams = Actual extends new (...args: infer P) => any @@ -101,7 +103,12 @@ export type ConstructorParams = Actual extends new (...args: infer P) => : P : never -type MismatchArgs = Eq extends true ? [] : [never] +type MismatchArgs = Eq< + ActualResult, + ExpectedResult +> extends true + ? [] + : [never] export interface ExpectTypeOfOptions { positive: boolean @@ -121,14 +128,19 @@ export interface ExpectTypeOf { toBeSymbol: (...MISMATCH: MismatchArgs, Options['positive']>) => true toBeNull: (...MISMATCH: MismatchArgs, Options['positive']>) => true toBeUndefined: (...MISMATCH: MismatchArgs, Options['positive']>) => true - toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true + toBeNullable: ( + ...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']> + ) => true toMatchTypeOf: { (...MISMATCH: MismatchArgs, Options['positive']>): true (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true } toEqualTypeOf: { (...MISMATCH: MismatchArgs, Options['positive']>): true - (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true + ( + expected: Expected, + ...MISMATCH: MismatchArgs, Options['positive']> + ): true } toBeCallableWith: Options['positive'] extends true ? (...args: Params) => true : never toBeConstructibleWith: Options['positive'] extends true ? (...args: ConstructorParams) => true : never @@ -187,7 +199,9 @@ export type _ExpectTypeOf = { * @description * See the [full docs](https://npmjs.com/package/expect-type#documentation) for lots more examples. */ -export const expectTypeOf: _ExpectTypeOf = (_actual?: Actual): ExpectTypeOf => { +export const expectTypeOf: _ExpectTypeOf = ( + _actual?: Actual, +): ExpectTypeOf => { const nonFunctionProperties = [ 'parameters', 'returns', @@ -234,5 +248,5 @@ export const expectTypeOf: _ExpectTypeOf = (_actual?: Actual): ExpectTyp const getterProperties: readonly Keys[] = nonFunctionProperties getterProperties.forEach((prop: Keys) => Object.defineProperty(obj, prop, {get: () => expectTypeOf({})})) - return obj as ExpectTypeOf + return obj as ExpectTypeOf } diff --git a/test/errors.test.ts b/test/errors.test.ts index 4fd1261f..755b5cfa 100644 --- a/test/errors.test.ts +++ b/test/errors.test.ts @@ -18,8 +18,8 @@ test('toEqualTypeOf<...>() error message', async () => { 3 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " @@ -43,8 +43,8 @@ test('toMatchTypeOf<...>() error message', async () => { 3 expectTypeOf({a: 1}).toMatchTypeOf<{a: string}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:135:16 + 135 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " @@ -58,8 +58,8 @@ test('toMatchTypeOf(...) error message', async () => { 3 expectTypeOf({a: 1}).toMatchTypeOf({a: 'one'}) ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:127:36 - 127 (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:136:36 + 136 (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. " @@ -86,8 +86,8 @@ test('usage test', () => { 21 expectTypeOf({a: 1, b: 1}).toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:35:25 - error TS2554: Expected 1 arguments, but got 0. @@ -95,8 +95,8 @@ test('usage test', () => { 35 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:135:16 + 135 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:38:25 - error TS2554: Expected 1 arguments, but got 0. @@ -104,8 +104,8 @@ test('usage test', () => { 38 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:42:24 - error TS2554: Expected 2 arguments, but got 1. @@ -113,8 +113,8 @@ test('usage test', () => { 42 expectTypeOf({a: 1}).toMatchTypeOf({b: 1}) ~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:127:36 - 127 (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:136:36 + 136 (expected: Expected, ...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:51:25 - error TS2554: Expected 1 arguments, but got 0. @@ -122,8 +122,8 @@ test('usage test', () => { 51 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:135:16 + 135 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:52:25 - error TS2554: Expected 1 arguments, but got 0. @@ -131,8 +131,8 @@ test('usage test', () => { 52 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:61:25 - error TS2554: Expected 1 arguments, but got 0. @@ -140,8 +140,8 @@ test('usage test', () => { 61 expectTypeOf().toBeNumber() ~~~~~~~~~~~~ - src/index.ts:117:16 - 117 toBeNumber: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:124:16 + 124 toBeNumber: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:65:43 - error TS2554: Expected 1 arguments, but got 0. @@ -149,8 +149,8 @@ test('usage test', () => { 65 expectTypeOf<{deeply: {nested: any}}>().toEqualTypeOf<{deeply: {nested: unknown}}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:83:27 - error TS2554: Expected 1 arguments, but got 0. @@ -158,53 +158,53 @@ test('usage test', () => { 83 expectTypeOf(undefined).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:124:18 - 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:132:5 + 132 ...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:87:22 - error TS2554: Expected 1 arguments, but got 0. 87 expectTypeOf(null).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:124:18 - 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:132:5 + 132 ...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:90:33 - error TS2554: Expected 1 arguments, but got 0. 90 expectTypeOf<1 | undefined>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:124:18 - 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:132:5 + 132 ...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:91:28 - error TS2554: Expected 1 arguments, but got 0. 91 expectTypeOf<1 | null>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:124:18 - 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:132:5 + 132 ...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:92:40 - error TS2554: Expected 1 arguments, but got 0. 92 expectTypeOf<1 | undefined | null>().toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:124:18 - 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:132:5 + 132 ...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:96:19 - error TS2554: Expected 1 arguments, but got 0. 96 expectTypeOf(1).toBeUnknown() ~~~~~~~~~~~~~ - src/index.ts:112:17 - 112 toBeUnknown: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:119:17 + 119 toBeUnknown: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:97:19 - error TS2554: Expected 1 arguments, but got 0. @@ -212,8 +212,8 @@ test('usage test', () => { 97 expectTypeOf(1).toBeAny() ~~~~~~~~~ - src/index.ts:111:13 - 111 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:118:13 + 118 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:98:19 - error TS2554: Expected 1 arguments, but got 0. @@ -221,8 +221,8 @@ test('usage test', () => { 98 expectTypeOf(1).toBeNever() ~~~~~~~~~~~ - src/index.ts:113:15 - 113 toBeNever: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:120:15 + 120 toBeNever: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:99:19 - error TS2554: Expected 1 arguments, but got 0. @@ -230,8 +230,8 @@ test('usage test', () => { 99 expectTypeOf(1).toBeNull() ~~~~~~~~~~ - src/index.ts:122:14 - 122 toBeNull: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:129:14 + 129 toBeNull: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:100:19 - error TS2554: Expected 1 arguments, but got 0. @@ -239,8 +239,8 @@ test('usage test', () => { 100 expectTypeOf(1).toBeUndefined() ~~~~~~~~~~~~~~~ - src/index.ts:123:19 - 123 toBeUndefined: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:130:19 + 130 toBeUndefined: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:101:19 - error TS2554: Expected 1 arguments, but got 0. @@ -248,17 +248,17 @@ test('usage test', () => { 101 expectTypeOf(1).toBeNullable() ~~~~~~~~~~~~~~ - src/index.ts:124:18 - 124 toBeNullable: (...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']>) => true - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/index.ts:132:5 + 132 ...MISMATCH: MismatchArgs, Options['branded']>>, Options['positive']> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:106:35 - error TS2554: Expected 1 arguments, but got 0. 106 expectTypeOf().toMatchTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:126:16 - 126 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:135:16 + 135 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:130:71 - error TS2554: Expected 2 arguments, but got 1. @@ -266,8 +266,8 @@ test('usage test', () => { 130 expectTypeOf>().exclude().toHaveProperty('xxl') ~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:137:5 - 137 ...MISMATCH: MismatchArgs, Options['positive']> + src/index.ts:149:5 + 149 ...MISMATCH: MismatchArgs, Options['positive']> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:147:21 - error TS2554: Expected 2 arguments, but got 1. @@ -275,8 +275,8 @@ test('usage test', () => { 147 expectTypeOf(obj).toHaveProperty('c') ~~~~~~~~~~~~~~~~~~~ - src/index.ts:137:5 - 137 ...MISMATCH: MismatchArgs, Options['positive']> + src/index.ts:149:5 + 149 ...MISMATCH: MismatchArgs, Options['positive']> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:152:41 - error TS2554: Expected 1 arguments, but got 0. @@ -284,8 +284,8 @@ test('usage test', () => { 152 expectTypeOf(obj).toHaveProperty('a').toBeString() ~~~~~~~~~~~~ - src/index.ts:118:16 - 118 toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:125:16 + 125 toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:159:27 - error TS2554: Expected 1 arguments, but got 0. @@ -293,8 +293,8 @@ test('usage test', () => { 159 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:179:19 - error TS2554: Expected 1 arguments, but got 0. @@ -302,8 +302,8 @@ test('usage test', () => { 179 expectTypeOf(f).toBeAny() ~~~~~~~~~ - src/index.ts:111:13 - 111 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:118:13 + 118 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:180:27 - error TS2554: Expected 1 arguments, but got 0. @@ -311,8 +311,8 @@ test('usage test', () => { 180 expectTypeOf(f).returns.toBeAny() ~~~~~~~~~ - src/index.ts:111:13 - 111 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:118:13 + 118 toBeAny: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:183:46 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'. @@ -328,8 +328,8 @@ test('usage test', () => { 246 expectTypeOf([1, 2, 3]).items.toBeString() ~~~~~~~~~~~~ - src/index.ts:118:16 - 118 toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true + src/index.ts:125:16 + 125 toBeString: (...MISMATCH: MismatchArgs, Options['positive']>) => true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:250:25 - error TS2554: Expected 1 arguments, but got 0. @@ -337,8 +337,8 @@ test('usage test', () => { 250 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:262:31 - error TS2554: Expected 1 arguments, but got 0. @@ -346,8 +346,8 @@ test('usage test', () => { 262 expectTypeOf<{a: string}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:266:32 - error TS2554: Expected 1 arguments, but got 0. @@ -355,8 +355,8 @@ test('usage test', () => { 266 expectTypeOf<{a?: number}>().toEqualTypeOf<{}>() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:267:32 - error TS2554: Expected 1 arguments, but got 0. @@ -364,8 +364,8 @@ test('usage test', () => { 267 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:268:32 - error TS2554: Expected 1 arguments, but got 0. @@ -373,8 +373,8 @@ test('usage test', () => { 268 expectTypeOf<{a?: number}>().toEqualTypeOf<{a: number | undefined}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:269:39 - error TS2554: Expected 1 arguments, but got 0. @@ -382,8 +382,8 @@ test('usage test', () => { 269 expectTypeOf<{a?: number | null}>().toEqualTypeOf<{a: number | null}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:270:37 - error TS2554: Expected 1 arguments, but got 0. @@ -391,8 +391,8 @@ test('usage test', () => { 270 expectTypeOf<{a: {b?: number}}>().toEqualTypeOf<{a: {}}>() ~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:278:22 - error TS2554: Expected 1 arguments, but got 0. @@ -400,8 +400,8 @@ test('usage test', () => { 278 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:284:22 - error TS2554: Expected 1 arguments, but got 0. @@ -409,8 +409,8 @@ test('usage test', () => { 284 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:301:28 - error TS2554: Expected 1 arguments, but got 0. @@ -418,8 +418,8 @@ test('usage test', () => { 301 expectTypeOf().toEqualTypeOf() ~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. test/usage.test.ts:316:35 - error TS2554: Expected 1 arguments, but got 0. @@ -427,8 +427,8 @@ test('usage test', () => { 316 expectTypeOf<{a: 1} & {b: 2}>().toEqualTypeOf<{a: 1; b: 2}>() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src/index.ts:130:16 - 130 (...MISMATCH: MismatchArgs, Options['positive']>): true + src/index.ts:139:16 + 139 (...MISMATCH: MismatchArgs, Options['positive']>): true ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arguments for the rest parameter 'MISMATCH' were not provided. "