Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript typings #525

Open
studds opened this issue Oct 2, 2018 · 16 comments
Open

Typescript typings #525

studds opened this issue Oct 2, 2018 · 16 comments

Comments

@studds
Copy link

studds commented Oct 2, 2018

Would you be open to a PR with some basic typescript typings, so that this can be used in typescript projects? They might not cover the full breadth and depth of the API, but would cover the most frequent use cases.

@kasperisager
Copy link

I'm currently working on TypeScript typings for Unexpected with a goal to cover as much of the API as possible. Since I need the typings for plugin development I expect to use the majority of the APIs available.

On a related note, might @papandreou or @sunesimonsen have an opinion on where these typings should live? They're currently internal to the project I'm working on but I'd love to make them more easily available. I know some people swear to DefinitelyTyped, which is a great resource for typings and all, though I do personally prefer as a consumer of a library not to have to install additional packages for things to Just Work™.

@papandreou
Copy link
Member

@kasperisager, that sounds really cool! If we can find a way to automatically generate the typings from the assertions that are defined and their types, I would be open to have the typings live in Unexpected itself. I remember @bruderstein talked about that idea earlier and seemed quite confident that it could be done.

If they have to be manually maintained, I think it would be better to keep them separate for the time being, as none of the maintainers use TypeScript, AFAIK.

@kasperisager
Copy link

That can absolutely be done, though the core typings (expect(), use(), clone(), addAssertion(), etc.) would still have to be maintained somewhere rather than generated. Currently, expect() is only minimally typed:

function expect<A extends Array<unknown> = []>(subject: unknown, assertionName: string, ...args: A): expect.Unexpected;

What could be done then is generate overloads based on assertion signatures, e.g. something like this...

expect.addAssertion<Person, [number]>(
  "<Person> [not] to be older than <number>", 
  (expect, subject, age) {
    // ...
  }
);

...would generate the following overload for expect():

function expect(subject: Person, assertionName: "to be older than" | "not to be older than", age: number): expect.Unexpected;

@sunesimonsen
Copy link
Member

I agree with @papandreou if it is not almost hands off then if should probably live somewhere else. The very dynamic nature of unexpected means that it will never be fully covered. But you might create something useful anyway. I don't use TypeScript, so I'm personally not super interested in maintaining it. But I can imagine an external project that takes the newest version of unexpected installs the most common plugins inspects the types and handlers on the unexpected instance and generates the type definitions.

@studds
Copy link
Author

studds commented Nov 12, 2018

fwiw, the official recommendation from the typescript team in this case would be to publish the types to the @types organisation on npm, which is done by submitting a PR to https://github.com/DefinitelyTyped/DefinitelyTyped.

The types could still be generated, of course. Has anyone made a start on this? @kasperisager are your types currently available anywhere publicly?

@kasperisager
Copy link

The typings I have so far can be found here: https://github.com/Siteimprove/alfa/blob/master/packages/alfa-unexpected/types/unexpected.d.ts

@alexjeffburke
Copy link
Member

This is really interesting - as it happens I recently did an experiment for the other part of this, which is to actually get auto-completion when writing assertions in test call. I'll see if I can get them cleaned up and arrive at a definition for all the assertions in core.

@studds
Copy link
Author

studds commented Dec 11, 2018

I've fleshed out the types we're using internally in preparation for opening a PR on DefinitelyTyped. I've also tried to combine with what you've got, @kasperisager. We're not doing any plugin development, though, so I'm not sure if this will work for that - would you mind having a look and letting me know?

https://github.com/studds/DefinitelyTyped/blob/master/types/unexpected/index.d.ts

@kasperisager
Copy link

I've pulled in your typings to see if our packages still type, and it looks like the only thing missing is either a general overload for the expect() function (similar to #525 (comment)) or the addition of optional conditions such as "[not] to be" which are used when defining new assertions: http://unexpected.js.org/api/addAssertion/

@kasperisager
Copy link

The general overload would actually be required regardless as there would otherwise be no way to invoke custom assertions. One of the issues I ran in to when implementing the typings used in our project was also that I couldn't find a way to allow plugins to define additional overloads for the expect() function, effectively making custom assertions only minimally typed. Unexpected itself will catch issues arising from that at runtime though so it was an acceptable trade-off.

@studds
Copy link
Author

studds commented Dec 12, 2018

Ahhh, yes, that is a problem. I can't figure out how to get around that with plain types.

Can I propose a different approach, in that case: wrapping unexpected and re-exporting it in a way that makes it more typescript friendly: https://github.com/studds/unexpected-ts#readme publish as https://www.npmjs.com/package/unexpected-ts

@kasperisager
Copy link

Your approach made me realise how it can be done with just a type declaration 👌 Voilá: Siteimprove/alfa@f0fa281

@studds
Copy link
Author

studds commented Jan 25, 2019

That's awesome, @kasperisager!

@msiebuhr
Copy link
Contributor

msiebuhr commented Aug 1, 2019

I ended up going @kasperisager 's typings and works for me (with a few tweaks).

IMHO, I don't think typing up all the different assertions is a terribly good idea. We add quite a few assertions of our own, and AFAIK, we wouldn't be able to add those to TSC run-time, making strict checking a no-go. The only benefit left is editor-typeahead (which I don't use much).

How about we get a MVP typings thing shipped and take it from there with adding more fancy stuff?

@kasperisager
Copy link

IMHO, I don't think typing up all the different assertions is a terribly good idea. We add quite a few assertions of our own, and AFAIK, we wouldn't be able to add those to TSC run-time, making strict checking a no-go. The only benefit left is editor-typeahead (which I don't use much).

On the contrary, the typings I've written allow both for strongly typed core assertions in addition to weakly typed custom assertions that can then be made strongly typed by extending the Expect interface from outside as seen here: https://github.com/Siteimprove/alfa/blob/f0fa281f3993706bbf67daedb147632594f09313/packages/alfa-unexpected/src/create-unexpected-plugin.ts#L10-L17

@shicks
Copy link

shicks commented Nov 28, 2021

Presumably one could take advantage of the (relatively) new template literal types to generate many possible assertions with only a few lines of declarations.

I'd love to be able to use this library, but without IDE support/completion of the assertion strings, it's a lot less appealing.

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

No branches or pull requests

7 participants