platform icon indicating copy to clipboard operation
platform copied to clipboard

Replace ts-snippet

Open jdegand opened this issue 4 months ago • 10 comments

Which @ngrx/* package(s) are relevant/related to the feature request?

NA

Information

ts-snippet is essentially deprecated. Running the type tests, there seems to be inconsistent results. It is tough to debug what is the problem. It may be worth looking at using tsd or tsx and converting the tests.

Describe any alternatives/workarounds you're currently using

No response

I would be willing to submit a PR to fix this issue

  • [ ] Yes
  • [ ] No

jdegand avatar Aug 21 '25 19:08 jdegand

Perhaps, you would be interested to consider TSTyche (https://tstyche.org) as well? I am its author.

TSTyche is the only type test runner that has test(), it() and describe() with .only and .skip. It can test agains specific version of TypeScript. Handles projects of any size and complexity (Effect, Immutable, Jest, are using TSTyche). The install size is only 260kB. Tiny, but it does more than any other similar tool. And I work everyday to make it even better.

mrazauskas avatar Aug 22 '25 09:08 mrazauskas

there seems to be inconsistent results

These inconsistencies are mainly caused by Nx, which sometimes behaves unpredictably when caching is enabled. Another issue is that the default setup for VSCode plugins and Vite doesn’t work out of the box with ts-snippet.


I’m in favor of replacing ts-snippet, but before we decide, it might be worth checking what other tools are available (e.g. TSTyche).

rainerhahnekamp avatar Aug 22 '25 11:08 rainerhahnekamp

what other tools are available

A list with popular type testing libraries and tools can be found here (and eslint-plugin-expect-type is yet another alternative and the owner of this list): https://github.com/JoshuaKGoldberg/eslint-plugin-expect-type?tab=readme-ov-file#references


Roughly there are three categories:

  • tsd and tstyche check types programatically using TypeScript APIs. These are independent runners, they do not require additional tooling. This is most flexible solution. It makes it easy to filter out unwanted types like any or never. Or to print out nice and readable error messages. The disadvantage: typescript must be patch to expose a method that checks if types are identical. That will not work with TypeScript 7. In the other hand, that internal method has some limitations, so this is chance for an improvement (https://github.com/tsdjs/tsd/issues/224, https://github.com/tstyche/tstyche/issues/443).

  • eslint-plugin-expect-type compares stringified types. Somewhat like a snapshot. This works fine, if a function returns string. But if the return type is JsonObject, it will get snapshotted as string literal 'JsonObject'. In the other hand this is how dtslint works, which is the internal testing tool of DefinitelyTyped.

  • other libraries are based on generic type manipulation. Users like them, because of red squiggles that are displayed in editor immediately. But.. Those messages are hard to read or even misleading. Filtering out any or never is not always possible. (Those are sneaking around even if library declares “first-class support” for those types, check the issues.) To run tests in CI you will need run tsc --noEmit or use Vitest (it simply runs the same tsc --noEmit in a spawned process), but that does not work with references in TSConfig.

As a conclusion, I think it is really nice to have quickly feedback in a form of red squiggles. In the other hand, tests are always part of CI. We write them once and they spin and spin. Therefore my preference is a CLI tool that: makes it a breeze to run tests; prints correct and readable messages; scales well.

But don’t listen to me (; Think about the requirements of your library.

mrazauskas avatar Aug 22 '25 12:08 mrazauskas

I have no real preference and those were the libraries that first came to mind. I will experiment and report any concerns.

jdegand avatar Aug 22 '25 18:08 jdegand

@jdegand let's also give a try to: https://www.npmjs.com/package/tsd

It seems to be widely used and "battle-tested" (300k+ weekly downloads) which is quite important to us.

markostanimirovic avatar Aug 22 '25 21:08 markostanimirovic

I think tsd could become a stop-gap solution. Its maintainer is overextended so tsd is likely going to see maintenance mode level of activity. Beyond bumps to TypeScript, I wouldn't expect much changes to that library.

I am also looking at expect-type.

jdegand avatar Aug 23 '25 16:08 jdegand

Since we're migrating towards Vitest, we can also make use of the built-in expectTypeOf(which uses expect-type under the hood) https://vitest.dev/guide/testing-types.html.

The only constraint compared to the current tests is that the error message cannot be verified AFAIK.

timdeschryver avatar Aug 25 '25 18:08 timdeschryver

From what I’ve seen with ts-snippet, you can feed it any string, configure a tsconfig.json, and then run the TypeScript compiler on it. That lets you introspect certain types by passing string literals, and so on.

Initially, I also leaned toward more “direct” typing tests like expectTypeOf, but I’ve come to appreciate ts-snippet’s more “raw” approach.

That said, we may not need all of that power. If an integrated solution like Vitest already provides what we need, it might be the better choice. The simplest way to find out is to try it on the type tests in @ngrx/signals.

rainerhahnekamp avatar Aug 25 '25 18:08 rainerhahnekamp

Yes, Vitest can't verify TypeScript error messages without external tools. I think the only real drawback besides that could be a false confidence in its results. I think it will potentially miss incorrect typing when the incorrect typing doesn't cause runtime-errors. I really haven't dug into the tests to see how involved they are, but Vitest might be good enough.

jdegand avatar Aug 25 '25 19:08 jdegand

We need error coverage as well. Especially for those kind of tests where we test that a variable is not of a certain type.

For example STATE_SOURCE should not be exposed, etc. // @ts-expect-error might work for that.

I don't think that we have tests where we use multiple tsconfig.json. That could be a problem.

rainerhahnekamp avatar Aug 25 '25 19:08 rainerhahnekamp