Skip to content

Nullish coalescing operator (??) #26578

Closed
@samclaus

Description

@samclaus

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions