-
Notifications
You must be signed in to change notification settings - Fork 4
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
[total-functions/no-unsafe-readonly-mutable-assignment] False positive? #774
Comments
It's working as intended imo, though the error message could certainly do with some work. Consider each part of the source union separately:
Therefore But consider this scenario: type Source = { c: number; } | {};
type Destination = { c: number; } | { c?: undefined; };
const sourceVal1 = {};
const sourceVal: Source = Date.now() > 0 ? sourceVal1 : { c: 42 };
console.log(sourceVal); // Outputs '{}'
// doesn't compile
// sourceVal.c = 24;
// doesn't compile
// sourceVal.c = undefined;
// doesn't compile
// sourceVal1.c = 24;
// doesn't compile
// sourceVal1.c = undefined;
// This is the problematic assignment (as we'll see next). It's flagged by this rule.
const destValue: Destination = sourceVal;
// this compiles, but...
destValue.c = 1;
// Whoops, we mutated a seemingly immutable value, exactly what this rule seeks to flag
console.log(sourceVal1); // Outputs '{ "c": 1 }'
console.log(sourceVal); // Outputs '{ "c": 1 }' The error message could be improved to refer to the |
I think I'm starting to wrap my head around this, but it's surprisingly complicated, so bear with me. In your example, the line That line is in fact erroneous because the value stored in Relating this back to my example, I'm starting to grasp the problem but am still having trouble. I've come up with a simplified reproduction: function f(x: { n?: number }) {
x.n = 2;
}
f({ n: 1 }); // This works
f({}); // This works
f(Math.random() < 0.5 ? { n: 1 } : ({} as { n?: number })); // This works
f(Math.random() < 0.5 ? { n: 1 } : {}); // This raises a lint error (Unsafe "Mutable" to "Mutable" assignment. Source: "{ n: number; } | {}", destination: "{ n?: number | undefined; })
// For fun, a couple more examples:
const v1: {} = {};
f(v1); // This raises a lint error, as I would expect it to
const v2: { n?: number } = {};
f(v2); // This works, as expected Given your explanation, I can kind of understand the error now: the value From a pragmatic point of view this is clearly wrong: my intent as a programmer is that the I suppose this is a quirk on TypeScript's end that you have no control over? I'm curious to hear your thoughts. Thanks for your consideration. |
Hi,
I'm getting the following error:
On the following code:
I'm new to eslint-plugin-total-functions, but it seems to me that the error message doesn't make sense: it's complaining that a mutable value is being assigned to a mutable argument? Is this error being thrown incorrectly, or am I misunderstanding the message?
The text was updated successfully, but these errors were encountered: