Description
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.