tsdx icon indicating copy to clipboard operation
tsdx copied to clipboard

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

Open karol-majewski opened this issue 5 years ago • 8 comments

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

karol-majewski avatar Jul 24 '20 14:07 karol-majewski

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.

agilgur5 avatar Jul 26 '20 17:07 agilgur5

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:

  • swallowed the provided types
  • rejected valid calls
  • returned any
  • returned never
  • didn't work with generic props
  • didn't work with props expressed as a union

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:

  • Affordance (or lack thereof). People don't know it's even possible.
  • Few developers can write quality definitions, so good enough definitions are usually good enough.
  • TypeScript-specific libraries have only started to become a thing.

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.

karol-majewski avatar Jul 26 '20 21:07 karol-majewski

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.

MrLoh avatar Aug 01 '20 16:08 MrLoh

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.

KATT avatar Jan 31 '21 14:01 KATT

@KATT I ended up using dtslint.

karol-majewski avatar Feb 01 '21 11:02 karol-majewski

@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 avatar Feb 03 '21 23:02 KATT

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

KATT avatar Feb 07 '21 12:02 KATT

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

MrLoh avatar Feb 09 '21 02:02 MrLoh