-
Notifications
You must be signed in to change notification settings - Fork 30.2k
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
[jquery] Remove type parameter from JQueryStatic
#26674
[jquery] Remove type parameter from JQueryStatic
#26674
Conversation
The type parameter does not provide additional type safety. It also forced unnecessary type assertions in some usage scenarios.
@leonard-thieu Thank you for submitting this PR! 🔔 @borisyankov @choffmeister @Steve-Fenton @Diullei @tasoili @jasons-novaleaf @seanski @Guuz @ksummerlin @basarat @nwolverson @derekcicerone @AndrewGaspar @seikichi @benjaminjackman @s093294 @JoshStrobl @johnnyreilly @DickvdBrink @King2500 - please review this PR in the next few days. Be sure to explicitly select If no reviewer appears after a week, a DefinitelyTyped maintainer will review the PR instead. |
Since you're a listed owner and the build passed, this PR is fast-tracked. A maintainer will merge shortly. If it shouldn't be merged yet, please leave a comment saying so and we'll wait. Thank you for your contribution to DefinitelyTyped! |
// $ExpectType JQuery<Document> | ||
myDoc; | ||
myDoc.on('click', (evt) => { | ||
let target = evt.target; | ||
const target = evt.target; | ||
// $ExpectType Document | ||
target; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is intuitive but wrong.
The target property can be the element that registered for the event or a descendant of it.
So probably it is HTMLElement or SVGElement. The test should be
myDoc.on('click', (evt) => {
let target = evt.target;
// $ExpectType Document|HTMLElement
target;
});
Perhaps the typing should be
on(events: string,
handler: JQuery.EventHandler<TElement | HTMLElement> | JQuery.EventHandlerBase<any, JQuery.Event<TElement>> | false): this;
But the following code should compile, as in reality a mouse interaction event will not have a target with, too. But this does not compile...
myDoc.on('click', (evt: JQuery.Event<HTMLElement|SVGElement>) => {
let target = evt.target;
// $ExpectType HTMLElement|SVGElement
target;
});
And thanks a lot for the notification :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been brought up before in #17377. There's a couple of solutions to the problem but none of them are particularly clean.
First off, let's keep in mind that there are 4 target properties on JQuery.Event
.
currentTarget
The current element within the event bubbling phase.
delegateTarget
The element that the handler was attached to. With the way the declarations are currently defined, this property is the only one that has the correct type.
relatedTarget
Another DOM element involved in the event. Set for mouseout
and mouseover
events.
target
The element that initiated the event. This can be the element that registered the event (delegateTarget
) or a descendant.
Solution 1
The current solution. All target properties have the same generic type. This works well when TTarget
is some base type (e.g. HTMLElement
or SVGElement
), you're only working with 1 DOM, and you don't need to access properties of more specific types. It otherwise produces incorrect types or types that are too general.
Solution 2a
Set the target properties to a base type. EventTarget
would be the correct base type but wouldn't be very useful. This leads to correct typing but requires type assertions to be practical.
Solution 2b
Set the target properties to any
. This throws away type safety and autocomplete but is the most flexible.
Solution 3
Introduce type parameters for the other target properties. This allows the user to have the most accurate typings but is a bit unwieldy. This would introduce up to 3 more type parameters on top of the 2 existing. Ordering of the parameters is also significant. They should be arranged to minimize the number of parameters that need to be defined in common cases.
In addition to this, it should also keep in mind additional type parameters that could be introduced to fix the issue of properties being marked optional on JQuery.Event
when they are known to exist.
Of all these, I prefer Solution 3 for its accuracy. My concern is that mistakes in the implementation could mean a lot of breaking changes for consumers in order to fix them. I would prefer a more graceful solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit are not compatible with many other typings, with messages like:
All declarations of 'JQuery' must have identical type parameters.
Also, the comment style is not playing well with vscode:
* @see \`{@link https://api.jquery.com/find/ }\`
* @since 1.0
* @since 1.6
Can some of you look at this, and possible fix or revert this pr? @sandersn @leonard-thieu @holgeradam @Diullei @borislavjivkov @basarat @johnnyreilly
If it there are many breaking changes, I would suggest that it should have been a bigger version bump.
I will use the old version until it's resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit are not compatible with many other typings, with messages like:
All declarations of 'JQuery' must have identical type parameters.
Which typings? All current versions of typings from DefinitelyTyped should be compatible.
Also, the comment style is not playing well with vscode:
Could you elaborate on what you mean (include a screenshot)?
If it there are many breaking changes, I would suggest that it should have been a bigger version bump.
@types/*
packages do not follow semantic versioning. Instead, their major and minor version numbers match the version of the library they represent. I recommend locking @types/*
packages to a specific version for your needs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update all our business typings then.
The type parameter on
JQueryStatic
does not improve type safety and actually reduces type safety in certain scenarios. This PR removes the type parameter onJQueryStatic
and replaces it with member-level type parameters where appropriate.Previously, the following code was not possible.
$('.mysvgline')
would use the default type parameterHTMLElement
and would not be assignable tojSvgLineElement2
without a double assertion even though the returnJQuery
object could containSVGLineElement
objects at runtime. This change now makes it possible with the following syntax.@HolgerJeromin
Please fill in this template.
npm test
.)npm run lint package-name
(ortsc
if notslint.json
is present).Select one of these and delete the others:
If changing an existing definition:
Provide a URL to documentation or source code which provides context for the suggested changes: <>Increase the version number in the header if appropriate.If you are making substantial changes, consider adding atslint.json
containing{ "extends": "dtslint/dt.json" }
.