Replace ts-snippet
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
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.
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).
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:
-
tsdandtstychecheck 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 likeanyornever. Or to print out nice and readable error messages. The disadvantage:typescriptmust 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-typecompares stringified types. Somewhat like a snapshot. This works fine, if a function returnsstring. But if the return type isJsonObject, it will get snapshotted as string literal'JsonObject'. In the other hand this is howdtslintworks, 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
anyorneveris 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 runtsc --noEmitor use Vitest (it simply runs the sametsc --noEmitin a spawned process), but that does not work withreferencesin 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.
I have no real preference and those were the libraries that first came to mind. I will experiment and report any concerns.
@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.
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.
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.
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.
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.
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.