Javascript function parameter annotation
Hello, I am struggling to correctly annotate a function that should accept an HTMLElement or any subtype of it.
For instance, if I define the function:
/**
@param {HTMLElement} target
*/
function foo(target) { ...}
And have a value of type HTMLInputElement:
/** @type {HTMLInputElement} */ const myInput = document.createElement('input');
When I try to pass myInput to foo, I get "Argument type HTMLInputElement is not assignable to parameter type HTMLElement".
I have also tried to declare the function with a constrained template:
/**
@template {HTMLElement} E
@param {E} target
*/
But then I still get a type mismatch: "Argument type HTMLInputElement is not assignable to parameter type E".
I tried going through Closure Compiler's documentation and check Typescript's types definitions to see if I was missing anything, but I don't know how to get this typing annotation right.
I looked at YouTrack as well, but the most similar issue that I found there was about assigning the return of document.createElement to a variable of a specific type. And it seems to be fixed already.
In my perception, if a function expects a certain type, it should accept any type that extends it as well.
Any help with this situation?
Please sign in to leave a comment.
What IDEA version do you work with? Your first solution should be fine, and it works for me - I don't see any errors reported in 2019.2.1:
Hello Elena,
Thank you for the quick answer.
My current IDEA version is 2019.2.2
Considering your reply, I did a double check and the noticed that this indeed wasn't the entire scenario that's leading to the type mismatch.
My variable isn't actually typed statically, its type is inferred from a dynamic type cast, a minimal case which leads to the type mismatch is like the following:
This isn't the actual code I'm using, nor I use it in such a simplistic way, it's really a minimal scenario to illustrate how I get the type mismatch. But after myInput is assigned through this cast, IDEA says that it is of type HTMLInputElement, but then gives a type mismatch.
No type mismatch errors are reported for me when using your example:
Could it be some setting that I'm using then?
Here's the inspection message I get:
Can you recreate it in a new project?
No, but I get a validation error on the cast:
I can see it too; why do you need it, BTW? Return type is taken from @return {T}, the is no need in additional casting
Oh, yes... That's right. Maybe it was reminiscent from some previous iteration of my code. I dropped this explicit cast.
Since the validation error doesn't happen on a clean project, I tried moving the .idea folder to another location and reopen the project folder to create a clean project, yet the same message appeared after IDEA indexed the files.
>yet the same message appeared after IDEA indexed the files
Must be smth specific to your project code/dependencies...
I'm gonna dig through the project and run some tests to see if I can find the cause then...
Thanks for the help for now.
I'd like to point out that I discovered the source of my struggle, although I don't understand why IDEA was reacting this way.
At another point in my project's directory structure, I had a cloned copy of immutable-js's source direct from its github directory. As soon as I deleted the "type-definitions" folder, the type mismatch message went away.