Skip to content

Conversation

@smallsaucepan
Copy link
Member

@smallsaucepan smallsaucepan commented Feb 1, 2026

Introduces tsd into an initial package to replace the tsc types.ts tests. tsd checks independently from tsc and provides some additional functionality around type checking e.g. expectError.

A test like the one included in this PR would have caught #3006.

This is an initial trial for the dev environment. If successful we can migrate existing types.ts files over package by package.

Please provide the following when creating a PR:

  • Meaningful title, including the name of the package being modified.
  • Summary of the changes.
  • Heads up if this is a breaking change.
  • Any issues this resolves.
  • Inclusion of your details in the contributors field of package.json - you've earned it! 👏
  • Confirmation you've read the steps for preparing a pull request.

@smallsaucepan
Copy link
Member Author

Would be good to get this (or something like it) in place so we can use it to support changes like #3012.

@mfedderly
Copy link
Collaborator

This looks pretty slick 🎉

How useful are the errors when you get a failing test? I used something similar before with vitest but the errors on complicated types were super unhelpful towards figuring out what went wrong. We had to break complicated types into their constituent parts manually to figure out what wasn't lining up, and then build it up from there to get something working.

I'd be willing to adopt this today even with unhelpful errors coming out of expectType / expectAssignable, but if they had usable errors that's even better.

@mrazauskas
Copy link

Please also consider TSTyche for testing types: https://tstyche.org. I am its author.

Take a better look at the tsd repo. Sadly, it is a rather abandoned project. Although I really like their idea of comparing types programmatically. One of the benefits: clear error messages. (As far as I know, only tsd and tstyche are comparing types programmatically; other libraries are implemented as generic types, producing errors that come with multi-page instructions on how to read them.)

To mention a few benefits of TSTyche:

  • errors are clear (there is nothing misleading, although, to be honest, they are not yet detailed enough, but this is what I will improve soon)
  • test() and describe() helpers with .skip and .omit
  • matchers like .not.toBeCallableWith()
  • checks of error messages silenced by // @ts-expect-error
  • tests against several versions of TypeScript
  • loads the installed TypeScript instead of shipping a patched copy (hence the install size is only 300kB instead of tsd’s 39MB)

@smallsaucepan
Copy link
Member Author

@mfedderly the error messages from tsd were comparable to what you'd see from tsc. Plenty good enough to act as a type checking canary. Though what do you think about TSTyche? I'll put together a comparison PR.

Thanks for bringing TSTyche to our attention @mrazauskas!

@smallsaucepan
Copy link
Member Author

smallsaucepan commented Feb 5, 2026

Example error output for comparison with TSTyche output in #3020:

> @turf/line-offset@7.3.3 test:types /Users/james/turf/packages/turf-line-offset
> tsd


  test-d/index.test-d.ts:36:32
  ✖  36:32  Argument of type Feature<LineString, { [name: string]: any; } | null> | Feature<MultiLineString, { [name: string]: any; } | null> is not assignable to parameter of type Feature<LineString, GeoJsonProperties>.
  Type Feature<MultiLineString, { [name: string]: any; } | null> is not assignable to type Feature<LineString, GeoJsonProperties>.
    Type MultiLineString is not assignable to type LineString.
      Types of property type are incompatible.
        Type "MultiLineString" is not assignable to type "LineString".
  ✖  37:37  Argument of type Feature<LineString, { [name: string]: any; } | null> | Feature<MultiLineString, { [name: string]: any; } | null> is not assignable to parameter of type Feature<MultiLineString, GeoJsonProperties>.
  Type Feature<LineString, { [name: string]: any; } | null> is not assignable to type Feature<MultiLineString, GeoJsonProperties>.
    Type LineString is not assignable to type MultiLineString.
      Types of property type are incompatible.
        Type "LineString" is not assignable to type "MultiLineString".

  2 errors

@mrazauskas
Copy link

Note that the tsd output mentions assignability instead of identically. This is because expectType() is implemented as a generic function. The message you see is simply forwarded from the compiler. In other words, try passing the file through tsc and the message will be the same.

Comparing objects with some nested any property or using expectNotType() is another story.

Worth mentioning that tsd’s negative assertions are not implemented as generic functions. In some cases, this inconsistency between implementations is causing the same test to pass with both expectType() and expectNotType() (tsdjs/tsd#141).

Another aspect, as you see tsd emits only errors. Which version of TypeScript was used? Which test files were actually checked? Sure, test-d/index.test-d.ts‎ is checked. But some time later a contributor will follow the existing pattern and add test-d/new.test-d.ts‎. That file will not checked. (I saw these situations around, unfortunately. Could we tsd --listFiles, perhaps? Nope. That does not exist either.)


Sorry, if this comment sounds too negative. As I mentioned, I really like tsd’s idea of comparing types programmatically. Also, I try to see what is missing and to build a better tool (first of all, for myself). As I also mentioned, TSTyche’s messages will have detailed explanations in the near future. (This is related to the rewrite that was shipped with TSTyche 6 in December. Obviously, at the moment, that is only a promise.)

You know the requirements of your project. So use what suits you best.

Copy link
Collaborator

@mfedderly mfedderly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving this one as well for the optionality, but probably we should go with tstyche

@smallsaucepan
Copy link
Member Author

Closing this PR in favour of using tstyche #3020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants