-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Cannot access property that exists only on some union members #36194
Comments
Related to the declined #33736. |
@jcalz The OP there is actually quite similar - but the issue has been closed because the control flow narrowing effects are undesired. My intent here is just to get the non-chained property access. I've read in other issues that this behavior requires exact types (so we cannot pass a |
This has been the behavior for about five years now; #1260 would be the issue to follow if you expect changes. |
@RyanCavanaugh is it realistic to expect such a change (for example in combination with exact types) at some point in the future? |
We'd have to think about it. Just hypothesizing, let's say you had type A = exact { x: number, y: number };
type B = exact { a: string, b: string };
declare const ab: A | B; What would be the ideal rules here?
|
I have no good answer for that. The example you posted is clearly much more complicated than my simple use case of a single property access. |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
I disagree that that is bonkers. The question mark makes it clear that either the left or right term might be undefined. Yes, we are loosing the fact that precisely one of them might be undefined, but that seems like a fair tradeoff. For example if you allow access to anything defined in the union, but as optional properties:
You will still get an error |
@patrickjcurran the error is because you're trying to concatenate possibly undefined values: type A = { x: number, y: number };
type B = { a: string, b: string };
declare const ab: A | B;
type LaxAB = Partial<A> & Partial<B>
const laxAb: LaxAB = ab;
const test1 = laxAb.a?.toLowerCase();
const test2 = laxAb.x?.toFixed()
test1 + test2; // Error here! |
@AlCalzone understood, my point was that it is good that the type checker doesn't allow that. I'll edit my post to make that more clear. Thank you. |
TypeScript Version: Nightly
Search Terms: Union property does not exist
Code
Expected behavior:
I can access
options.baz
and its type isnumber | undefined
.Actual behavior:
Error: property baz does not exist on type
SomeOptions
. The workaround does work, but is unnecessarily verbose and does unnecessary runtime checks.I know this is mentioned in the handbook, but I'd like to advocate for this behavior to be reconsidered. It was mentioned that the type at runtime might be different than expected, but this is also true for the workaround.
I also know I could add all these properties to the other union members (
baz?: never
), but this is quite tedious and error prone for complex real-world types.Playground Link: https://www.typescriptlang.org/play/?ts=3.8.0-dev.20200114&ssl=1&ssc=1&pln=15&pc=2#code/JYOwLgpgTgZghgYwgAgMoHsC2EDyAHMYdEAZ2QG8AoZG5GddALmQCMGAbCOEAbkoF9KlUJFiIUOMAAto+QsTJVarOFGZt0nbn2Us4ALwD8zEAFdMLaH0GUYpkAnkhkAE3QZs00AHMAFOgIiUmYPXECFZAAfZEkZKDkgkgBKCmpaAHp05ABRKCh0NTSaBAUwFX0ARmQAXmQApxIAOj19ZENDZAqdDKyAdQKAaxJGIuQS0jKWgCYa5F8AIhb55FA68NI2tYbmg2RmexcIGFAIFxT2zusgA
Related Issues:
if (foo.bar?.bizzle) { /* this is fine */ }
The text was updated successfully, but these errors were encountered: