-
Notifications
You must be signed in to change notification settings - Fork 12.8k
optional elements in objects cannot be ensured to be defined #39762
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
It also knows that the object can still be mutated:
|
That is a good point actually! But if |
I feel compelled to mention that
|
I did not know that. Honestly, in that case I am actually not sure anymore if |
Duplicate of #16976, I think. I don't see mutations as being the main issue here; control flow analysis could presumably narrow upon checking and then re-widen upon an assignment, much as it does in this case: function toRequired(foo: string | undefined): string {
if (foo === undefined) { throw new Error("element is undefined"); }
return foo; // okay
}
function toRequiredBad(foo: string | undefined): string {
if (foo === undefined) { throw new Error("element is undefined"); }
foo = undefined; // I mutated it
return foo; // error here
} It's mostly that the compiler does not attempt to narrow the type of non-union-typed values, even if they contain properties that are themselves union types. I imagine performance would take a major hit if every check of a union-typed value had implications for any values depending on it. Discriminated unions are possibly a way to proceed here, since they're one of the few places (or only place?) in which checking an object's property can narrow the type of the object itself. It still has to be a union-typed object, though, like this: type Foo = ({ element: number }) & ({ optionalElement: string } | { optionalElement?: undefined });
function toRequired(foo: Foo): Required<Foo> {
if (foo.optionalElement === undefined) { throw new Error("element is undefined"); }
foo.optionalElement = undefined; // error, won't let you mutate
return foo; // okay
} |
Duplicate #10065 |
Since #10065 was closed and locked, you're essentially saying that this won't be fixed/changed? |
Never say never, but it's unlikely to be any time soon. It would require a fairly invasive rethinking of how the checker reasons about types. |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
TypeScript Version: 3.9.7, 4.0.0 beta, Nightly
Search Terms: required elements, type assertions
Code
Expected behavior:
It would be nice if
toRequired
would compile as well, as typescript knows thatoptionalElement
is defined (as demonstrated intoRequired2
.Actual behavior:
toRequired
fails to compile and requires either destructuring or type casts.Playground Link:
Playground Link
The text was updated successfully, but these errors were encountered: