Skip to content

Add 'Nullable' built-in utility type #39522

Closed
@wessberg

Description

@wessberg

I've made a PR

Search Terms

Nullable

Suggestion

TypeScript already comes with a NonNullable type, defined in lib.es5.d.ts:

/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T extends null | undefined ? never : T;

I propose that its inverse, Nullable, is added to the built-in type utilities.

I'm aware that your general position in terms of built-in type utilities is that you don't extend them unless strictly necessary, but I do think this is an important addition for the following reason:

The built-in type utilities generally offer inverse types. For example, Partial is the inverse of Required. And, Pick is the inverse of Omit. Because of this, to me it naturally follows that NonNullable should have an inverse called Nullable.

Use Cases

For the following examples, nullable is defined as null or undefined, thereby following TypeScripts definition from the NonNullable utility type.

A few examples that comes to mind:

  • Required keys with nullable values.
  • Function arguments that may have a nullable value.

Additionally, it may help with simplifying built-in type definitions:

For example in lib.es5.d.ts, the catch and then declarations for the Promise interface can be simplified:

interface Promise<T> {
    then<TResult1 = T, TResult2 = never>(onfulfilled?: Nullable<(value: T) => TResult1 | PromiseLike<TResult1>>, onrejected?: Nullable<(reason: any) => TResult2 | PromiseLike<TResult2>>): Promise<TResult1 | TResult2>;
    catch<TResult = never>(onrejected?: Nullable<(reason: any) => TResult | PromiseLike<TResult>>): Promise<T | TResult>;
}

There are several types, particularly in lib.dom.d.ts that could also be simplified by leveraging the Nullable type.

Examples

As part of an InterfaceDeclaration:

interface Foo {
    prop: Nullable<string>;
}

As a optional parameter to a function that may also accept null:

function validateUserInput (text: Nullable<string>): void {}

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. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions