jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.26k stars 508 forks source link

Add out-of-the-box support for type tests #781

Open karol-majewski opened 4 years ago

karol-majewski commented 4 years ago

Current Behavior

tsdx allows me to test my code using Jest out of the box. That's great. But I wish I could test my types as well.

Desired Behavior

Out-of-the-box support for testing types using dtslint or similar library.

Suggested Solution

  1. Introduce dtslint, ts-expect or a similar library to all tsdx templates.
  2. Create a directory for type tests.
  3. Run type tests when the default test task is run.

Who does this impact? Who is this for?

All users. tsdx is TypeScript-oriented, and unit-testing types helps preventing accidental breaking changes in these.

Describe alternatives you've considered

A guide explaining how one can test their types in a project bootstrapped with tsdx.

Additional context

agilgur5 commented 4 years ago

Could you help me understand the use-case here? dtslint, tsd, etc are used for testing type declaration files, i.e. .d.ts files. Given that TSDX's main use-case is to enable TypeScript-first development, most users of TSDX would not be authoring .d.ts files as those are auto-generated for them from their .ts files.

All users. tsdx is TypeScript-oriented, and unit-testing types helps preventing accidental breaking changes in these.

I think this is a good bit smaller than that as it's a subset of users that write tests and a much smaller subset of that that would write type tests. I've only seen type tests a few times and IIRC almost entirely within the context of DefinitelyTyped. Even if this proposal were accepted, given the small user-base, it would inevitably be de-prioritized / backlogged.

karol-majewski commented 4 years ago

Motivation

Could you help me understand the use-case here?

Of course. Let's assume your library exposes a higher-order React component. If it ships with TypeScript definitions, the consumers of your library would be pretty disappointed if the component:

Without type tests, how can you guarantee the expected TypeScript behavior? It's easy to break someone's build by accidentally affecting the inferred types, which leads to frustration and hours lost.

Examples

dtslint, tsd, etc are used for testing type declaration files

Not always. When we look at the ecosystem, we find repositories where unit tests are complemented by type-level tests. Examples: redux-toolkit, fast-check, ramda.

Other libraries, such as ts-toolbelt, utility-types or type-plus, are focused solely on type-level operations. For such libraries, good type inference is not just a nice-to-have. Sometimes, it's the goal.

The growing demand

I think this is a good bit smaller than that as it's a subset of users that write tests and a much smaller subset of that that would write type tests.

That's right. I ran a survey and it confirmed how unpopular this practice currently is. I would risk a hypothesis that these are the reasons:

There is no reason to believe things will stay this way, though. The expectations of the users are growing, and the definition of what constitutes a quality library is changing. Poor TypeScript experience is a legitimate reason to disqualify a library and choose another one instead.

Additionally, the more developers enter the ecosystem, the higher quality of the typings we're going to see.

It would be a shame to let silly mistakes creep in.

MrLoh commented 4 years ago

Testing your types should really be a best practice for libraries that are written in typescript and expose non trivial components such as higher order components or discriminated union prop types. Having this build into tsdx would be a huge step into the right direction.

KATT commented 3 years ago

Did you manage to integrate anything like this, @karol-majewski?

I'm developing a library that has a lot of crazy type inference & would like to have the testing automated as it's quite often that something ends up being any rather than an explicit type. I tried to add eslint-plugin-expect-type to my eslint, but it didn't wanna play ball.

karol-majewski commented 3 years ago

@KATT I ended up using dtslint.

KATT commented 3 years ago

@karol-majewski do you have a reference project where you got it integrated into a lib or something? I can't get it to work nicely

KATT commented 3 years ago

I was able to easily add this package: https://github.com/mmkal/ts/tree/main/packages/expect-type

Works great for me, can be added in the jest files

MrLoh commented 3 years ago

I have a library with working type tests here https://github.com/MrLoh/styled-native-components/blob/master/tests/typings.test.tsx