open-wc / custom-elements-manifest

Custom Elements Manifest is a file format that describes custom elements in your project.
https://custom-elements-manifest.open-wc.org/
234 stars 43 forks source link

Type inference for custom events TypeScript #134

Open remcovaes opened 2 years ago

remcovaes commented 2 years ago

I have a feature request for type generation for events.

I would like to write the following code:

/**
* Some extra info
*/
this.dispatchEvent(new CustomEvent<{ bar: string }>('foo', {
    detail: {
        bar: 'baz'
    }
}));

Would it be possible to infer the type of the event foo to the type argument { bar: 'baz' }?

This would save me from duplicating the information to a comment, which can get out of sync with the code. This also allows TypeScript to check if my event detail has the correct type.

What I have to write right now:

/**
* Some extra info
*
* @type {{ bar: string }}
*/
this.dispatchEvent(new CustomEvent('foo', {
    detail: {
        bar: 'baz'
    }
}));

The simular package web-component-analyzer does this (there are other reasons why I am not using that package). See the [example of event typing](https://runem.github.io/web-component-analyzer/?code=export%20class%20TextField%20extends%20HTMLElement%20%7B%0A%20%20_fooEvent()%20%7B%0A%20%20%20%20%2F**%20Some%20text%20*%2F%0A%20%20%20%20this.dispatchEvent(new%20CustomEvent%3C%7B%20bar%3A%20string%20%7D%3E(%27foo%27%2C%20%7B%0A%20%20%20%20%09detail%3A%20%7B%20bar%3A%20%27baz%27%20%7D%0A%20%20%20%20%7D))%3B%0A%20%20%7D%0A%20%20_barEvent()%20%7B%0A%20%20%20%20%2F**%0A%20%20%20%20*%20Some%20text%0A%20%20%20%20*%0A%20%20%20%20*%20%40type%20%7B%7B%20bar%3A%20string%20%7D%7D%0A%20%20%20%20*%2F%0A%20%20%20%20this.dispatchEvent(new%20CustomEvent(%27bar%27%2C%20%7B%0A%20%20%20%20%09detail%3A%20%7B%20bar%3A%20%27baz%27%20%7D%0A%20%20%20%20%7D))%3B%0A%20%20%7D%0A%7D%0A%0AcustomElements.define(%22text-field%22%2C%20TextField)%3B%0A%0A%0A%0A)

thepassle commented 2 years ago

I think we can improve on this by checking for typeArguments on the node?.parent (the newExpression), before this line (jsdoc should always override):

https://github.com/open-wc/custom-elements-manifest/blob/9067c13c0dcd84075c7c2f76878552493531a007/packages/analyzer/src/features/analyse-phase/creators/createClass.js#L185

id be happy to review a PR for this