Repository navigation
Nullish coalescing operator (??) #26578
Description
Search Terms
- nullish coalescing
Suggestion
A nullish coalescing operator, which is essentially an alternative to || that will only return the right-side expression if the left-side is null or undefined (|| returns the right-side if the left-side is falsy, i.e. null | undefined | "" | 0 | false | NaN).
Use Cases
This would be extremely useful anywhere where defaults are needed for potentially omitted inputs, but empty strings or 0, and so forth, are valid inputs that shouldn't be defaulted. My particular use case is AngularJS component bindings. Whenever bindings are updated, I would like to provide a default for a string or boolean binding only when they are straight up omitted (undefined), but I have to do a full-fledged ternary expression with typeof to handle the falsy input corner-case.
In conjunction with the safe chaining operator (#16), handling optionals would be trivial.
Examples
export interface Configuration {
// Default: "(no name)"; empty string IS valid
name?: string;
// Default: -1; 0 is valid
items?: number;
// Default: true
active?: boolean;
}
function configureSomething(config: Configuration) {
// With null-coalescing operator
config.name = config.name ?? "(no name)";
config.items = config.items ?? -1;
config.active = config.active ?? true;
// Current solution
config.name = typeof config.name === "string" ? config.name : "(no name)";
config.items = typeof config.items === "number" ? config.items : -1;
config.active = typeof config.active === "boolean" ? config.active : true;
// Using || operator (INCORRECT)
config.name = config.name || "(no name)"; // does not allow for "" input
config.items = config.items || -1; // does not allow for 0 input
config.active = config.active || true; // really bad, always true
}Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript / JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. new expression-level syntax)
Activity
jhpratt commentedon Dec 9, 2018
Andy (Andrewkraft) (@Andy-MS) Shouldn't the tag be waiting for TC39, not out of scope?
MatthiasKunnen commentedon Jun 10, 2019
Nullish coalescing has reached stage 2. Can this issue be reopened or will this be addressed elsewhere?
davidje13 commentedon Jul 7, 2019
Matthias Kunnen (@MatthiasKunnen) given the close connection, I'm guessing this will be brought in along with #16, but the general rule seems to be to wait for stage 3, so we have a bit longer to wait yet.
natew commentedon Jul 24, 2019
Stage 3 now!
jhpratt commentedon Jul 24, 2019
^^ source
DanielRosenwasser commentedon Jul 24, 2019
You're welcome!
Kingwl commentedon Jul 24, 2019
Could i take a try on this?
DanielRosenwasser commentedon Jul 24, 2019
Ron Buckton (@rbuckton) has an old branch that implements this (I would link you to it but it's searchable and I'm on mobile), so it depends on how bad the merge conflict would be and whether he would mind.
12 remaining items
rbuckton commentedon Aug 4, 2019
Ryan Cavanaugh (@RyanCavanaugh): tsx/jsx
RyanCavanaugh commentedon Aug 14, 2019
Hey folks (in particular Wenlu Wang (@Kingwl) and Titian Cernicova-Dragomir (@dragomirtitian)) - we'd love to have this feature shipped as a headlining "community-implemented" feature in 3.7. I think whoever claims dibs first can put up a draft PR and then hopefully work with others to contribute fixes, finish things out, and add testcases.
Sheetal Nandi (@sheetalkamat) will be helping coordinate and offer advice / code review throughout the process.
Thanks!
dragomirtitian commentedon Aug 14, 2019
Ryan Cavanaugh (@RyanCavanaugh) Hey, I have a 6 day chunk of time free time starting tomorrow, so I can start on this right away.
Sheetal Nandi (@sheetalkamat) Should I start from Ron Buckton (@rbuckton) 's old branch? Or should I start from scratch?
Thanks!
Kingwl commentedon Aug 14, 2019
Titian Cernicova-Dragomir (@dragomirtitian)
I already have a migrated branch, based Ron Buckton (@rbuckton) commit (and a few changes). Could we work on it?🤔
dragomirtitian commentedon Aug 14, 2019
Wenlu Wang (@Kingwl) Hi, sure, I'd be happy to collaborate on what is already there. Are you on gitter ? Maybe we can sync there as to what work still needs to be done and how to divide it up.
Kingwl commentedon Aug 14, 2019
Titian Cernicova-Dragomir (@dragomirtitian) Sure, Thanks
Fortunately, I'm at UTC+8 and you are at UTC+3😍
fix(VCombobox): compare vs null/undefined as opposed to falsey in sel…
nisimjoseph commentedon Oct 15, 2019
thank you so much on the feature!
I played with it a little and saw the TS 3.7-Beta generate extra parenthesis in the end result, see here:
https://www.typescriptlang.org/play/index.html?ts=3.7-Beta#code/JYOwLgpgTgZghgYwgAgKoGdrIN4FgBQyRycAJqVBOugPwBcR2yBxryCwYAng+mFKADmLNkQAOAez4BhCaQi9+QkUQC+BdfgLyEAGziV2EkH2QBXTFACMDDNG0Q9BlAmOmL0AEy3LBAsBhkAAoPa2QaGnNLTwBKHBVmfFUgA
DanielRosenwasser commentedon Oct 15, 2019
You're welcome! If you would like to suggest improvements, feel free to open another issue.
the21st commentedon Feb 18, 2020
What about the question raised by Anders Lassen (@Duckers) ? I'm curious what's the recommended syntax there. Is there a plan to add safe coalescing operator to replace
&&?samhh commentedon Feb 18, 2020
Simon Sotak Gregor (@the21st) This is a more appropriate question for TC39, perhaps here.
dantonel commentedon Jun 2, 2020