-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Spreading props in JSX on right hand side of && operator gives incorrect undefined warning #48326
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
Comments
Here's a simplified example of what you're trying to do: const value = undefined as string | undefined
const obj = { value }
if (value) {
const expected: string = obj.value
} Narrowing the value you stored in an object previously will not narrow the object. |
Thanks for the fast reply @MartinJohns! So in that case, in your example, changing the if statement to const ComponentTwo = ({ titleTwo }: ComponentTwoProps) => {
const componentOneProps = {
title: titleTwo,
};
return componentOneProps.title && <ComponentOne {...componentOneProps} />;
}; That should solve the error from my understanding of your reply, am I missing something? I'm not sure why TypeScript still thinks |
Narrowing the property
|
Ok @MartinJohns - do you know if support for this will be added into TypeScript? It would be great if it was able to handle this and it seems like it crops up in the issues here quite often. This comment from @RyanCavanaugh suggests that it may be possible to add support for this, although that was over a year ago now. |
As far as I was aware, "not narrowing the parent type based on individual properties" is deliberate for performance/complexity reasons (so as not to create large intersection types, e.g.) and the tradeoff is that TS provides support for discriminated unions as an alternative. |
@fatcerberus do you have a link for this somewhere? Would be interested in this. Another thing that surprised me that does not work is this (Playground): function fn(h: { a: string; b?: never; c?: never } | { a: string; b: string; c: string }) {}
let data = 'a' as 'a' | undefined;
// β
This works in TS
fn(data ? { a: '', b: '', c: data } : { a: '' });
// β TS cannot figure this option out, even though it's also valid
fn({
a: '',
...(data && { b: '', c: data }),
});
// β This also fails
fn({
a: '',
...(data ? { b: '', c: data } : {}),
});
// β
This works in TS
fn({
a: '',
...(data ? { b: '', c: data } : {} as {[key: string]: never}),
});
// β
This also works in TS
fn({
a: '',
...(true && { b: '', c: '' }),
}); |
@karlhorky See this comment, which in turn links to this comment chain. |
In particular this is relevant:
in other words, the effective type of any reference is found by working backwards through the control flow graph, and having to narrow at all levels of an object would give the compiler a lot more work. |
I created a new issue #50922 just in case any of this is actually a bug |
@RyanCavanaugh I saw you closed this as "completed" - is the original problem described by @samtjo now fixed in the latest nightly / main branch? Is there somewhere we can read about the change? Or is this rather supposed to be closed as "wontfix"? (eg. maybe because of same reasons from #50922 (comment) ?) |
The bulk "Close" action I applied to Design Limitation issues doesn't let you pick what kind of "Close" you're doing, so don't read too much into any issue's particular bit on that. I wish GitHub didn't make this distinction without a way to specify it in many UI actions! The correct state for Design Limitation issues is closed since we don't have any plausible way of fixing them, and "Open" issues are for representing "work left to be done". |
Bug Report
π Search Terms
Spread, Spreading, &&
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wG4AocmATzCTgGFdIA7JFmAeTYAUcwAznAC8cAN7k4cGMBgAbJAC44AmFGAsA5hQC+FcmggtVjZkfZc2IuAAox02Qrg7lTcOY7ckfCIICUIgB84pJwRDAArlAscAA8ABYAjIFiMvJIOrEA9EmBuvo0dKbubBwAKgDuED6C1hJSaQqVEAD8yqrqWvmUhsbwbqwWzdZ2DunDLsWD5VU1AgHCwfVwvSaGJRZec3WhDY5KY01VADSheqHhUTGNSMMAZHdxAx6W9GIAdJ-r069zOnBZPLkc7kJAAD0gsDgABMkJgUBE5P0zKUYM0KFksnAALLUFYQWFwTQQJBCeJIIhAA
π» Code
π Actual behavior
Because we checking that
titleTwo
is truthy here (as it's the first operand of the logical AND operator) - thetitle
prop ofComponentOne
can never actually be set toundefined
, but we get a warning saying typeType 'string | undefined' is not assignable to type 'string'.
π Expected behavior
I would expect no error here, as the
title
prop can never be actually set to a falsey value onComponentOne
there. I think this may be an issue with spreading the props ontoComponentOne
here as it works if you set thetitle
prop directly:The text was updated successfully, but these errors were encountered: