tsdjs / tsd

Check TypeScript type definitions
MIT License
2.4k stars 67 forks source link

`expectType` generic causes incorrect inference #142

Open mmkal opened 2 years ago

mmkal commented 2 years ago

expectType doesn't work properly with generic functions. Here's a repro:

import {expectType} from 'tsd'

declare const inferrable: <T = 'SomeDefaultValue'>() => T

expectType<number>(inferrable()) // passes, should fail

I'm not sure if it's possible to fix given the API design, but here's the same test using expect-type which fails as it should.

import {expectTypeOf} from 'expect-type'

declare const inferrable: <T = 'SomeDefaultValue'>() => T

expectTypeOf(inferrable()).toEqualTypeOf<number>() // fails as expected, because `inferrable()` returns type `'SomeDefaultValue'`
ilchenkoArtem commented 2 years ago

I have this issue too

tommy-mitchell commented 2 years ago

Added a test. @sindresorhus do you have any idea how to go about fixing this? From the conversation in dot-prop it seems no, but it could be worth further looking into.

sindresorhus commented 2 years ago

do you have any idea how to go about fixing this?

No

sindresorhus commented 2 years ago

Added a test

Can you submit it it (commented out)?

tommy-mitchell commented 2 years ago

By submit it do you mean as a PR?

sindresorhus commented 2 years ago

Yes

tommy-mitchell commented 1 year ago

See #196 for discussion on this.

SamVerschueren commented 1 year ago

Given how TypeScript and generics work, I think currently the only way of solving this is by storing the result of the inferrable() call in a variable first

declare const inferrable: <T = 'SomeDefaultValue'>() => T

const val = inferrable();

expectType<number>(val);

TypeScript forces the generic to fit in the argument. And there doesn't seem to be a way to prevent this. It would be fixed by something like expectNumber() or expectString(). But if you have much more complex types, tsd can't offer an expectXXX for everything 🤷 . I'll think about a possible solution 🤔 .