-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
"The 'this' context of type 'Foo | Bar' is not assignable to method's 'this' of type 'Foo'" with a this constraint that shouldn't have any effect #54407
Comments
I think this is just a design limitation in that the compiler mostly sees |
@fatcerberus But in that case, |
Yeah, you're right. I tried this: public overload_ko_param(x: Foo): void;
public overload_ko_param(x: any): void;
public overload_ko_param(x: any): void {} with an equivalent method on |
Changing the versions of |
From TS's analysis perspective, this code isn't distinguishable from this class Foo {
foo = 1;
public ok(): void {}
public ko(this: Foo): void {}
}
class Bar {
bar = 2;
public ok(): void {}
public ko(): void {}
}
function f(x: Foo | Bar, y: Foo | Bar): void {
x.ok();
x.ko.call(y);
} which actually is unsound. |
Bug Report
🔎 Search Terms
The this context of type is not assignable to methods this of type
Found #23304, #28777, and #51198 which all seem somewhat different.
🕗 Version & Regression Information
Passing in TS 3.5.1, failing in TS 3.6.3 and above (including nightly 5.2.0-dev.20230526)
(haven't tried intermediate versions since they are not in the Playground)
(not seeing anything obvious in the 3.6 release notes
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
The calls to
x.ko()
andx.overload_ko()
throw type errors inf
.🙂 Expected behavior
So, the signatures of
ko
andok
are slightly different (inFoo
), but sinceko
is already a method on the classFoo
, it should only be called whenthis
is an instance ofFoo
anyway, so it feels like the "this constraint" shouldn't do anything.The
overload_*
cases feel even weirder. Inoverload_ok
, the first overload is definitely a catch all, so it is the only one used (as far as I understand), and since it is the same as theok
signature, everything works.But in
overload_ko
, the first overload is the same as theko
signature and fails for the same reason, but the second overload (which is the same as theok
signature and thus should work) is not even tried (my IDE also says it is never called). So, it seems that TS treats the first overload (ofoverload_ko
) as a catch all case and stops looking further… except it is actually not behaving the same way. TS even tries to be helpful adding:Since the implementation signature is exactly the same as the second overload, this shows that TS totally ignored the second overload, yet doesn't treat the first one as being fully a catch all case, since stuff breaks with the first one that would work with the second.
g
is a workaround where forcing the narrowing and breaking the union in advance resolves the problem. However, having to WET my code is not really doable in practice; and having both the "then" and "else" branchs with the exact same code is such an anti-pattern that it makes my programmer lizard brain scream 🙈Of course, there may be something I do not really understand in what the "this constraint" actually does. This looks very weird from where I stand now.
The text was updated successfully, but these errors were encountered: