Hacker News new | ask | show | jobs
by acemarke 1460 days ago
We do a _lot_ of this in the Redux library repos (examples: [0] [1] [2] ). We have some incredibly complicated types in our libraries, and we have a bunch of type tests to confirm expected behavior.

Generally, these can just be some TS files that get compiled with `tsc`, but it helps to have a bunch of type-level assertions about expected types.

I actually recently gave a talk on "Lessons Learned Maintaining TS Libraries" [3], and had a couple slides covering the value of type tests and some techniques.

[0] Redux Toolkit's `createSlice`: https://github.com/reduxjs/redux-toolkit/blob/9e24958e6146cd...

[1] Reselect's `createSelector`: https://github.com/reduxjs/reselect/blob/f53eb41d76da0ea5897...

[2] React-Redux's `connect`: https://github.com/reduxjs/react-redux/blob/720f0ba79236cdc3...

[3] https://blog.isquaredsoftware.com/2022/05/presentations-ts-l...

1 comments

Hey Mark, I’m actually currently looking at a similar problem.

I’m writing a HTTP client based on composition. The exact details aren’t important, but one of the goals is to have a strong type system for describing a valid pipeline of things like response parsers. Imagine something like

Doing “type tests” alone isn’t too hard - we can just use conditional types and the extends keyword. If the code compiles, fine.

But the harder part is negative type tests. “Given this code, the developer should get this error from TSC”. But this is just as important a part of the API; your types are there to convince the consumer that they can call a type-checked API with confidence.

In theory it should be plausible to run TSC programmatically. The issue is that TypeScript’s ScriptProcessor API really wants to be called with files on the filesystem rather than source text. So I am having to do some bodging. If I can get something sorted I may write a repo to demo it, I think it is a common problem.

Hmm. While it may not be the immediate answer to your question, my Redux teammate Lenz Weber ( @phryneas ) wrote a Remark plugin that parses TS codeblocks out of Markdown and actually runs them through the TS compiler. As part of that I know he generates a bunch of "virtual files", including some parsing that lets you add an extra section of the codeblock representing another file to be compiled along with the actual example. The source for that may at least help give you some examples of how to use TS programmatically:

https://github.com/phryneas/remark-typescript-tools

I use @ts-expect-error for testing the negative case, but if there was a practical way of testing the actual error reported that would be wonderful.
My solution to this was to run tsc from Jest tests and do snapshot tests for the error messages

https://github.com/noppa/get-optional/tree/master/tests/typi...