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

feat: improve typedefs #41

Merged
merged 2 commits into from
May 18, 2021
Merged

feat: improve typedefs #41

merged 2 commits into from
May 18, 2021

Conversation

vsgoulart
Copy link
Contributor

No description provided.

@CLAassistant
Copy link

CLAassistant commented Mar 31, 2021

CLA assistant check
All committers have signed the CLA.

@nikku
Copy link
Member

nikku commented Apr 15, 2021

Hi @vsgoulart! Thanks for your PR and sorry for not getting back earlier. The way I understand it these type definitions do make sense if each event contains the same payload. This, however is something we cannot guaranee. I.e. a destroy event fires without any payload.

Is there any generic patter that supports more general payloads?

@vsgoulart
Copy link
Contributor Author

vsgoulart commented Apr 15, 2021

Thanks for getting back @nikku
I was checking on options to overload the payload, which would generate types like this:

export default class FormCore {
  // ...
  on(event: 'submit' | 'changed', callback: (state: { data: Data; errors: Errors; }) => void): void;
  on(event: 'destroy', callback: () => void): void;
  // ...
}

But it looks like the TS compiler can't properly infer the types from JSDoc yet (I tried some of the examples of the alternative solutions there, but they didn't really help).

Considering that I have 2 suggestions.

Option 1:

/**
  * @type { (event: Events, callback: (state: EventPayload | undefined /* | any other type we might have */) => void) => void }
  */

The problem with this solution is that we can't match the event with the callback type, so the user would have to check the callback params. For example:

// Considering this is the annotation on JSDoc
// @type { (event: Events, callback: (state: EventPayload | undefined ) => void) => void }
// The user would have to do this
form.on('submit', (callbackOptions) => {
  if (callbackOptions === undefined) {
    return;
  }
  const {errors, data} = callbackOptions;
});

Option 2:
We just type the arguments as any like below and live with it until tsc implements overloading

/**
  * @type { (event: Events, callback: (state: any) => void) => void }
  */

This is one is slightly better than the types we have on main because the user won't have to cast the params to any but we won't be able to narrow the types for the user.

Of course there's always the option to manually create the types for TS, but it's not convenient and more prone to bugs.

@nikku
Copy link
Member

nikku commented May 17, 2021

Sorry for the long wait on a response, this issue somehow fell of my radar.

I'd personally go for your option 2 right now.

/**
  * @type { (event: Events, callback: (state: any) => void) => void }
  */

If that serves as an improvement for you could you update your contribution accordingly?

@nikku nikku added the help wanted Extra attention is needed label May 17, 2021
@vsgoulart
Copy link
Contributor Author

@nikku Updated

@nikku nikku removed the help wanted Extra attention is needed label May 18, 2021
@nikku nikku merged commit bd97030 into bpmn-io:master May 18, 2021
@vsgoulart vsgoulart deleted the improve-typedefs branch May 18, 2021 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants