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

[8.14.1] Type errors #8753

Open
boris-petrov opened this issue May 31, 2024 · 11 comments
Open

[8.14.1] Type errors #8753

boris-petrov opened this issue May 31, 2024 · 11 comments
Labels
needs: triage This issue needs to be reviewed

Comments

@boris-petrov
Copy link
Contributor

Description

Thanks for the new release! However, I believe there is an issue in the new types:

component.d.ts

ready(fn: (this: Component) => Component, sync?: boolean): Component;

The return type of the fn parameter is not supposed to be Component but rather void - I don't think we have to return values from the callback in the ready method, right?

Also, when called on the Player, isn't the this going to be the Player instance? As In that case the this argument is wrongly marked as Component:

Type 'Component' is missing the following properties from type 'Player': boundDocumentFullscreenChange_, boundFullWindowOnEscKey_, boundUpdateStyleEl_, boundApplyInitTime_, and 209 more.

Reduced test case

N/A

Steps to reproduce

Install video.js and use TS.

Errors

No response

What version of Video.js are you using?

8.14.1

Video.js plugins used.

No response

What browser(s) including version(s) does this occur with?

N/A

What OS(es) and version(s) does this occur with?

Linux

@boris-petrov boris-petrov added the needs: triage This issue needs to be reviewed label May 31, 2024
@gkatsev
Copy link
Member

gkatsev commented May 31, 2024

The ready method comes from Component, which Player inherits from. ready on a component, would have the this be that Component, which, in the case of Player, would be the player.
We don't override the method in player.js, but maybe we can use jsdoc to update the method signature there?

@boris-petrov
Copy link
Contributor Author

I'm not sure, maybe overriding the type signature is possible. This is not that important if it's difficult to fix as users can cast the usage in the function so it's kind-of OK. The other problem with the return type is breaking all usages of ready though.

@gkatsev
Copy link
Member

gkatsev commented May 31, 2024

yeah, these two lines should be removed. Not sure why they were re-added the last time that piece was touched:

* @return {Component}
* Returns itself; method can be chained.

@boris-petrov
Copy link
Contributor Author

I guess that is wrong, yes, because I don't see the code returning anything from ready. But will that fix the other issue that the fn argument is marked as returning Component? I don't understand how this maps to the fn parameter? I see fn defined as a ReadyCallback above this but I don't find a definition for ReadyCallback anywhere in the codebase.

@mister-ben
Copy link
Contributor

ReadyCallback is here, but I don't know why that is interpreted as it would return a Component

/**
* A callback that is called when a component is ready. Does not have any
* parameters and any callback value will be ignored.
*
* @callback ReadyCallback
* @this Component
*/

@boris-petrov
Copy link
Contributor Author

boris-petrov commented May 31, 2024

Looking in VSCode, when I hover over ReadyCallback, the tooltip says type ReadyCallback = /*unresolved*/ any. I'm not sure how this @callback annotation works. But maybe because TS can't resolve ReadyCallback it thinks that the line below (which says @return {Component}) also applies to it? But on the other hand I see that fn is defined with this: Component so it did somehow read the definition of ReadyCallback... I'm not sure, all these jsdoc annotations are really strange. 😄

@mister-ben
Copy link
Contributor

It's all very complicated because typescript understands a subset of jsdoc when generating the types, and also some typescript-specific syntax in jsdoc but which jsdoc itself doesn't understand, and breaks generating the API docs. Finding a balance that works for both is hard.

If I remove the @return from ready() and add @return {undefined} in Component.js, then component.d.ts has this:

ready(fn: () => undefined, sync?: boolean): void;

@boris-petrov
Copy link
Contributor Author

This also doesn't work, the return type must be void. Doesn't @return {void} work? Or simply removing @return?

@mister-ben
Copy link
Contributor

It looks like jsdoc is ok with using @param {function():void} fn ? The API docs output defines it as a function, and the type definition becomes ready(fn: () => void, sync?: boolean): void;. Seems simpler than defining ReadyCallback.

@mister-ben
Copy link
Contributor

{function():void} seems to work by accident rather than design, and would break jsdoc if it were any more complicated, e.g. documenting arguments. So not a good precedent to set. Going back to defined callbacks, I have this, which specifies this for the Player's callback but leaves Component's unspecified. Returning {void} isn't really right in jsdoc itself as js functions that don't explicitly return do return undefined. But it's probably well understood. Any thoughts?

@boris-petrov
Copy link
Contributor Author

I'm really not the person to review JSDoc. 😄 But as for the undefined - of course JavaScript itself doesn't have a concept of void but TypeScript does - and that's absolutely the right way to specify this function as it indeed does not return a value (even though there is an implicit return at runtime).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs: triage This issue needs to be reviewed
Projects
None yet
Development

No branches or pull requests

3 participants