Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected error tests involving typescript enums + zod #33

Open
electrovir opened this issue May 31, 2023 · 3 comments
Open

Unexpected error tests involving typescript enums + zod #33

electrovir opened this issue May 31, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@electrovir
Copy link
Sponsor

electrovir commented May 31, 2023

I have not been able to narrow down what is causing this, as simple examples in a TypeScript playground do not fail. However, I'm now having issues in version 0.16.0 with .toEqualTypeOf. I have a relatively complex type builder that I'm using to extract types out of run-time values and I run type testing with expect-type to ensure the extracted types are correct.

After upgrading to version 0.16.0 of expect-type, my test now fails even though, AFAICT, the types are indeed equal:

expectTypeOf<Pick<(typeof shapeDefinition.runTimeType), 'myEnum'>>().toEqualTypeOf<{
    myEnum: TestEnum;
}>();

Here's a playground with all the needed code from my package. The failing expectType is near the bottom. Apologies for the size of the code, I narrowed it down to the myEnum property but couldn't figure out how to narrow it further.

The workaround for me for now is to revert to version 0.15.0 as it has no issues for me.


edit

Smaller, self-contained repro:

import {z} from 'zod'
import {expectTypeOf} from '../src'

// eslint-disable-next-line no-restricted-syntax
enum ExampleEnum {
  a = 0,
  b = 1,
}

interface ExampleInterface {
  prop: ExampleEnum
  prop2: string
}

const InterfaceValidator = z.object({
  prop: z.nativeEnum(ExampleEnum),
  prop2: z.string(),
})
type InterfaceValidatorType = z.infer<typeof InterfaceValidator>

// this comparison fails
expectTypeOf<InterfaceValidatorType>().toEqualTypeOf<ExampleInterface>()
electrovir added a commit to electrovir/augment-vir that referenced this issue May 31, 2023
@mmkal
Copy link
Owner

mmkal commented Jun 2, 2023

Interesting. That does indeed seem wrong but I can't see why it'd be happening. It does seem to be specific to enums. I never use enums in general in typescript because behaviour is much harder to intuit and doesn't have any real advantages over, say string literals, so there are probably some tests missing for enums. Were you able to find a way to reproduce the issue that doesn't involve as many dependencies? That'd make it easier to track down.

@lsmurray
Copy link

lsmurray commented Sep 12, 2023

Here is another example with zod. Reported with vitest but if you change the import to use expect-type it has the same error.

vitest-dev/vitest#4114

@mmkal mmkal changed the title Version 0.16.0 breaks my type equality test Unexpected error tests involving typescript enums + zod Nov 6, 2023
@mmkal
Copy link
Owner

mmkal commented Nov 6, 2023

Still can't figure out exactly what causes this, but it is likely something quite deep in TypeScript, since the default toEqualTypeOf check now uses this technique: microsoft/TypeScript#55188 (comment).

But you can easily workaround this without downgrading by using .branded (which accesses the original, slower, implementation, of toEqualTypeOf):

import {z} from 'zod'
import {expectTypeOf} from '../src'

// eslint-disable-next-line no-restricted-syntax
enum ExampleEnum {
  a = 0,
  b = 1,
}

interface ExampleInterface {
  prop: ExampleEnum
  prop2: string
}

const InterfaceValidator = z.object({
  prop: z.nativeEnum(ExampleEnum),
  prop2: z.string(),
})
type InterfaceValidatorType = z.infer<typeof InterfaceValidator>

// this comparison now doesn't fail: ... 👇
expectTypeOf<InterfaceValidatorType>().branded.toEqualTypeOf<ExampleInterface>()

I'll leave this open though because microsoft/TypeScript#55188 was closed recently, so it might be worth checking regularly to see if this is fixed by a future typescript version.

@aryaemami59 aryaemami59 added the bug Something isn't working label Mar 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants