-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Rest binding element should contextually type initializer as a tuple #1824
Comments
This will only matter when you're destructuring a tuple using spread operator--which, I contend, is going to be a very rare. Futhermore, if we did this sort of partial tuple destructuring, wouldn't you also expect z to be of type Right now we have a simple rule that says whenever spread or rest is involved, the result is an array. I think anything beyond that gets very muddled. |
I agree that spread should make the result an array, because we don't know what you did to the array (lengthwise or elementwise) before you did the spread. However, rest seems different. I think with rest, there is no information lacking, that would cause it to be unsafe to consider the contextual type a tuple. To answer your questions about the above example:
I think doing this for rest, but not spread, is a sensible option. |
What about var [x, y, ...z] = [0, ""]; Would we then switch and make z an array? So sometimes you get an array and sometimes a tuple. I think there is more complexity here than meets the eye for practically zero gain. I just don't think it is a meaningful real world scenario and I'd rather have the simple rule. |
In that case, z would be a tuple of length 0, which happens to degenerate to I am not sure how anyone would gauge the benefits here. But the current rule about rest elements just doesn't seem to fit into our tuple story, and seems like changing it wouldn't cost us much. |
Existing behavior matches general pattern of not inferring a tuple type when none was written |
Rereading this, I think we should actually do something different from what I mentioned. We should contextually type the RHS as a tuple, but then z should always be an array that matches the array being destructured. That way x and y have the expected types, and z behaves as it does today. What would be wrong with that? |
Open question over whether this is the right thing to do or not, versus its priority relative other things (and our inability to change this if we decide to do it later) |
Thanks. I will also point out that this situation is not as rare as it may seem, if you consider that the binding pattern can be a parameter, and the array literal can be an argument. |
Doesn't seem to be coming up in real code. |
x and y are
string | number | boolean
because the rest element causes the contextual type to be an array. It seems like there is no reason for this. I think the contextual type here should be a tuple, so x would be number, y would be string, and z would be(string | boolean)[]
The text was updated successfully, but these errors were encountered: