emberjs/ember-test-helpers

Regression with `find()` generic type

nwhittaker opened this issue · 1 comments

Prior to the 2.9 release, find() supported a generic parameter that extended Element. This was useful in typing the return value in cases where a tag name was not a suitable selector:

E.g.

const { value } = find<HTMLInputElement>('.my-second-input')!;

This overload was previously supported because @types/ember__test_helpers was just passing through to document.querySelector types.

I see some discussion on this in #1287 (comment), but it's not clear how find<MyElement>('.my-element') is worse or different from the less convenient find('.my-element') as MyElement. Plus the former type is derived from the native document.querySelector types, so it feels like there should be a very good, clear reason to omit it. Otherwise it comes off as an over-opinionated decision.

While I understand your POV, this is strictly not a regression, it's an intentional change in the type to match the actual behavior. There is no way for find() to actually provide something of that type, so we are not going to ship a type definition which pretends it does.

While folks often use generics/type params like this as a convenient way to do a cast, there's a very good reason that most ESLint (and historically also TSLint!) rule sets forbid generic types which constrain the return type without any relation to an input parameter. That reason is: it is literally always a lie for a generic to appear on a call expression like this other than a constructor type (where it is narrowing what you can do with the returned type from an otherwise unconstrained default). Net: this was always an inappropriate use of a generic parameter.

To be clear: I understand why you might find the decrease in convenience annoying, especially in tests. But it's not a regression, and we're not going to revert it.

(And no, shipping something stronger than TS does is not necessarily "overly opinionated": TS has to balance not breaking every single piece of DOM code using TS out there against correctness, and they might well make different decisions today if starting from scratch!)