-
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
Narrow object by property #33205
Comments
I am against this being allowed. const banana: {prop:2} = apple
apple.prop = 5
console.log(banana.prop) //5, not 2, whoops |
I updated original to make |
Copy-pasting from Gitter, I understand your pain because, in some cases, you know that |
Also, const writable = { prop : 2 }
const apple : { readonly prop : number } = writable
//Snip narrow apple.prop to 2
const banana : { prop : 2 } = apple
writable.prop = 9001
console.log(banana.prop) //9001, not 2, whoops We can't modify |
@AnyhowStep Is the fact that you can assign |
It's not a bug. The current meaning of
We are not saying,
If Perhaps more surprising is that But if we keep in mind what It does limit the usefulness of const apple : { readonly prop : number } = { prop : 2 }
const writable : { prop : number } = apple
writable.prop = 1337 |
IIRC this is historical. I’m reasonably sure most of the unsoundness surrounding |
@MicahZoltu can you give an example that doesn't involve numbers? Right now it sounds like you want I also do not understand the intent of disallowing
but allowing
Did the second example predate the addition of readonly? |
|
@sandersn From the discussion on Gitter that led to this issue, the main point of contention was that What @MicahZoltu wanted, essentially, was for |
@fatcerberus is correct. To help exemplify the problem: declare const apple: { readonly prop: number }
if (apple.prop !== 2) throw new Error()
const appleProp: 2 = apple.prop // no error
// Type '{ readonly prop: number; }' is not assignable to type '{ readonly prop: 2; }'.
// Types of property 'prop' are incompatible.
// Type 'number' is not assignable to type '2'.
const banana: {readonly prop:2} = apple // error
const cherry: {readonly prop:2} = {prop: apple.prop} The assignment to Reading the issues linked above, a comment from @jack-williams in one of them indicates this is a design constraint:
Also, it would seem (based on @AnyhowStep's commentary above) that TypeScript thinks that while So IIUC, the current behavior is a design constraint, and @AnyhowStep thinks that even if it wasn't, it should not be fixed because |
@MicahZoltu Oh, I misunderstood your idea, and also didn't know that we already narrow numbers to numeric literals. Anyway, as @jack-williams says, this is exactly a duplicate of previous issues. And since it would require the compiler to synthesise new types, we haven't done it because of the performance implications. |
For future readers, this is a duplicate of #31755, which is a duplicate of #30506, which is closed as a Design Limitation (though it is missing a tag). The crux of the problem is:
The reason this is a Design Limitation is because:
|
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Search Terms
narrow object by property
(unfortunately, this returned way too many results to look through, so sorry if this is a dupe!)
Suggestion
Narrow objects based on checks of their properties.
Use Cases
Some function receives an object as input and then does validation on that object prior to passing it on to some other function, or returning it as a narrowed object.
Examples
In this example, we can see that the compiler is tracking the narrowed type of
apple.prop
because it allows us to assign it to a variable of type2
. However, when we try to assign the containing object to something that wants a narrowedprop
we get a type error.Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: