91

According to this article, when strict null checking is enabled in TypeScript, you cannot assign null or undefined to a variable unless it is explicitly allowed with a union.

// required value let req: string; req = "Something"; // OK req = null; // Error req = undefined; // Error // nullable value let nbl: string | null; nbl = "Something"; // OK nbl = null; // OK nbl = undefined; // Error 

But is null allowed in an optional value in TypeScript?

// optional value let opt?: string; // (actually invalid, as optional types cannot be used for variable declarations, but that's not the point, so imagine we are dealing with function parameters or something) opt = "Something"; // OK opt = null; // OK? Error? opt = undefined; // OK 

Or is

opt?: string; 

equivalent to

opt: string | undefined; 

thus not allowing null just like recommended by Microsoft's Coding guidelines?

2 Answers 2

149

EDIT: Important Note As Quentin C pointed out in the below comment, the behavior listed here is only when strict null checking is enabled: "strictNullChecks": true in tsconfig.json.


The types null and undefined are handled as separate types. The optional type is special, also allowing arguments to be left out of function calls.

1. Without a union or optional, nothing except the type itself is allowed.

function foo(bar: string) { console.info(bar); } foo("Hello World!"); // OK foo(null); // Error foo(undefined); // Error foo() // Error 

2. To additionally allow null, a union with null can be made.

function foo(bar: string | null) { console.info(bar); } foo("Hello World!"); // OK foo(null); // OK foo(undefined); // Error foo() // Error 

3. Allowing undefined works similarly. Note that the argument cannot be left out or null.

function foo(bar: string | undefined) { console.info(bar); } foo("Hello World!"); // OK foo(null); // Error foo(undefined); // OK foo() // Error 

4. You can also allow both, but the argument MUST still be given.

function foo(bar: string | null | undefined) { console.info(bar); } foo("Hello World!"); // OK foo(null); // OK foo(undefined); // OK foo() // Error 

5. With optional you can leave the argument out, or pass undefined, BUT NOT null.

function foo(bar?: string) { console.info(bar); } foo("Hello World!"); // OK foo(null); // Error foo(undefined); // OK foo() // OK 

6. To allow all three special cases, optional and null can be combined.

function foo(bar?: string | null) { console.info(bar); } foo("Hello World!"); // OK foo(null); // OK foo(undefined); // OK foo() // OK 

Also, optional is only usable in parameter or other type declarations, such as interfaces, not on regular variables. As it would make no sense to leave out the value of a variable when assigning to it.

Thus,

let d?: string; 

would make no sense and results in a compilation error.

Sign up to request clarification or add additional context in comments.

3 Comments

For people like me that don't read properly the question, the behavior listed here is only when strict null checking is enabled. "strictNullChecks": true in tsconfig.json
FYI, undefined isn't allowed in example #5 doesn't when "exactOptionalPropertyTypes": true is specified in tsconfig.js.
let d?: string; is not an assignment, it's a declaration. The keyword let makes this admittedly confusing. It does make sense to have declarations without assignment and that's why JS and many languages allow it, even for optionals/nullables/etc.
-3

let d?: string; declares the type as string | undefined.

This is because undefined is the default value for JS variables.

1 Comment

You are not right, let d?: string is not valid in TypeScript. See github.com/microsoft/TypeScript/issues/13321

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.