-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Allow destructured object entries with default parameters not to be optional #51179
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
Previously discussed at #30488. By design, type annotations are always the last word on anything. This is important for predictability and for performance. |
For those unable to follow, like me without a lot of head-scratching: @RyanCavanaugh seems to be saying that the following two lines should both throw the same error: const {a = 1}: {a: number} = {a: undefined};
const {a = 1}: {a: number} = {}; I respectfully disagree, I don't think either of them should throw an error, since it is promised that const {a = 1}: {a: number} = {}; // error cause we're expecting an object that contains a as a number, which {} is not
const {a: number = 1} = {}; // fine cause we're implicitly expecting any object, and we know that a is guaranteed to be a number Personally I'd want to see a case where it's ambiguous what the author intended and the transpilation is more complicated than just stripping out everything after the colon, which is generally what I think of as the defining feature of typescript. I don't know about performance but it seems unlikely that you need a whole bunch of overhead just to remember whether the destructuring had a default parameter or not when you check if an undefined value was passed in. |
I think the intent of this line is extremely clear: const {a = 1}: {a: number} = {};
Step 3 is unambiguous and what happens at step 4 is immaterial. Further proof of this intent is counterfactual: had I wanted |
I think the disconnect is that as a maintainer, you see the behavior of a type annotation as saying something about what objects can enter the zone it's responsible for, but as a user, I am thinking of its purpose as giving me guarantees about the code that follows. So to me as long as there's no earthly way for me to interfere in the middle of an expression, I want the annotation to tell me what types the expression gives me, not what I can pass into it. This might be the wrong way of thinking about it but it's the only use typescript has to me if I'm coding, I don't really care about initializing bindings with an object I just want the stuff in the object. |
const {a = 1}: {a: number} = {}; self-evidently and unambiguously (:p) says that we are destructuring an object and that what we'll have after is a number called "a", which is true |
It depends on what you think destructuring is a sugar for. If you wrote const obj: {a: number} = {};
const a = obj.a === undefined ? 1 : obj.a; then the type error is still there. TS is consistent about this view of what destructuring means: const {a = 1}: Partial<{a: number}> = {};
a // correctly number, not number | undefined Obviously there are multiple ways to interpret the situation, but both have trade-offs and your view of this being an incompleteness is someone else's view of a possible lack of error here being an unsoundness. |
Yeah that's what I'm trying to get at, you said this was "discussed" but in both cases it was just a post by you that's basically impenetrable to users. I understand the need for maintainers to have a consistent philosophy, I just think it's helpful to have it written out what the disagreement is because users rarely have to think of it that way. const {a = 1}: {a?: number} = {}; The fact that this does not result in a |
I'm not sure what you want me to do? |
I wanted you to make that comment that explains it! Thank you, unironically! |
Happy to help π |
Uh oh!
There was an error while loading. Please reload this page.
Suggestion
π Search Terms
default value optional object destructure
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
If a default value is set on a required field in an object, I wish Typescript allowed an undefined value to be passed in without throwing an error.
I don't think this would be a breaking change because it will only affect situations that are currently errors.
I feel like there's probably something fundamentally weird about the way I'm thinking about it, but I wanted to at least create an issue so that other people could find it, as I wasn't able to find anything on this.
π Motivating Example
This throws an error, but I believe that this is readable, and as far as I understand it Javascript could never allow the value of a to be undefined in such cases.
π» Use Cases
The primary use case is for React prop interfaces:
This shows an error unless a is made optional, but it doesn't seem like there's anything wrong or confusing about this to me.
The text was updated successfully, but these errors were encountered: