Cannot reassign undefined to the parameter of a function parameter destructuring with default value
🔎 Search Terms
"function parameter destructuring", "destructured parameter", "named parameter", "undefined"
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about "Why Method Bivariance?"
⏯ Playground Link
https://www.typescriptlang.org/play/?target=0&ts=5.7.0-dev.20241018#code/GYVwdgxgLglg9mABGOAnAtgQwDYAVOqboCmUxqAYuNPGABQEDmAXIgEZxzbGZIA+icABNiwGGGJDEAXkRRUIYgEpEAbwBQiLYiaI+fWcNHjJAbnUBfdetCRYCRCIDO8kNBCpJ+QiTKVq9vSqOqiMMnIKxIgWrMFMrBxcPPyCYCJiElIWKhoAkLr6hmnGmeZWNgG0jsQuCu6eQgDyAA6BON5EpORUdrR0caHhrlExaiGMAPwJnNy80Tnq+YOFqekmQmXWtjQOzq71XgSdfj07YACM-eNDkTpO7DPJeqslktGx49NJcwJGGW-ZNSLAoGF7-DaWLaVXY1fZQDyHHxdfy9BAAJiuulGAxYD2+KT+62i4RxrGG8yBSzCK0JpUhQA
💻 Code
function normalParameterFunction(arg: boolean | undefined = true) {
arg ||= undefined;
}
function destructuredParameterFunction({ arg = true }: { arg: boolean | undefined }) {
arg ||= undefined;
}
function destructuredOptionalParameterFunction({ arg = true }: { arg?: boolean }) {
arg ||= undefined;
}
🙁 Actual behavior
The normalParameterFunction works fine, but in destructuredParameterFunction and destructuredOptionalParameterFunction, I cannot assign undefined to arg.
Type 'undefined' is not assignable to type 'boolean'.
🙂 Expected behavior
I know that if I specify the default value to the arg, the arg will no longer be undefined, but maybe I can reassign it to the undefined.
I guess it should have the same logic as the following:
var arg: boolean | undefined = true;
arg ||= undefined;
Additional information about the issue
-
I don't know if it's really a bug or if it's a bad habit to change the value of a function parameter, but the function without parameter destructuring work as expected. Also, I hate recreate a new variable and come up with a new name in order to change the value of a function parameter, even though assigning the parameter itself directly doesn't modify the variable outside the function.
-
The above code is a real-world use case that aims to set
argtoundefinedwhen it is a falsy value. In fact,arg ||= undefinedis not needed, justarg = undefinedwill trigger the issue, but in this case, the original value ofargis ignored and has no practical meaning. -
You can also pass the type check in disguise with the following code:
function destructuredParameterFunction1({ arg = true as boolean | undefined }: { arg: boolean | undefined }) {
arg ||= undefined;
}
function destructuredParameterFunction2({ arg }: { arg: boolean | undefined } = { arg: true }) {
arg ||= undefined;
}
Prior feedback was that people felt that something with a default should be thought of as "not ever undefined" and that's the current logic. There's a lot of different interpretations on exactly how parameter and destructuring defaults should be thought of (i.e. equivalent to the caller having never passed undefined in the first place vs being a short-circuit assignment at the top of the function).