Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Union Types with Null and Nullable Object declaration in Typescript

I recently found a bit of typescript code in a bigger angular project, that had a Bitwise-OR/Pipe-Symbol within its object declaration. Like this:

dataSource: FileSource | null;

In my understanding it is an object of the type FileSource that is also nullable.

dataSource = null; // Works
dataSource = new FileSource... // Works
dataSource = 32; // Error


I also found out that you can declare an object with a whole set of Datatypes like this:

myVariable: number | string | null;

Now to my actual question: I can as well declare an object with a question mark as a symbol for nullable. Is there any difference between these two declarations?

myVariable: FileSource | null;
mySecondVariable?: FileSource;

If there is no difference between these two, would you consider it a bad practice, as it is not common in other languages and no valid javascript code?

BTW: In Javascript this:

myVariable: Number | null;
myVariable = "Hello World";

would be fine.

My focus is the nullability of an object and how these declarations differ

like image 377
Babofett Avatar asked Oct 19 '18 13:10

Babofett


People also ask

What is nullable type in TypeScript?

TypeScript Nullable is a special type null that has the value null. TypeScript Null is much like void, i.e. not useful on its own. By default, null is a subtype of all other subtypes which means a user can assign null to any of the data types like string, number, etc.

What is union types in TypeScript?

In TypeScript, we can define a variable which can have multiple types of values. In other words, TypeScript can combine one or two different types of data (i.e., number, string, etc.) in a single type, which is called a union type. Union types are a powerful way to express a variable with multiple types.

Is null an object in TypeScript?

The null in TypeScript is a special value & also a data type. The value null represents the intentional absence of any object value. It is one of TypeScript's primitive values and is treated as falsy for boolean operations. The value of null is represented in using the literal null .

Should I use null or undefined TypeScript?

You may use either, just be aware of the differences and it might make sense to be consistent. The TypeScript coding style guide for the TypeScript source code (not an official "how to use TypeScript" guide) states that you should always use undefined and not null : Typescript Project Styleguide.


2 Answers

Is there any difference between these two declarations?

Yes, particularly with strict null checks. A property with a union type (the | symbol) is required to be present with a value that matches one of the types.

An optional property (declared with ?) is just that: Optional. The object isn't required to have it at all. Although that said, at the moment (at least), TypeScript treats prop?: X exactly like prop: X | undefined; see this issue helpfully pointed out by jcatz.

Without strict null checks, this is fine:

type A = {
    dataSource: Date | null
};
type B = {
    dataSource?: Date
};

const a: A = { dataSource: null }; // Works
const b: B = { dataSource: null }; // Also works

With strict null checks, the second is wrong:

type A = {
    dataSource: Date | null
};
type B = {
    dataSource?: Date
};

const a: A = { dataSource: null }; // Works
const b: B = { dataSource: null }; // Error: Type 'null' is not assignable to type 'Date | undefined'.

Live Example in the Playground

Similarly, assigning undefined would be fine without strict null checks, but with them, it's an error in the union type case:

type A = {
    dataSource: Date | null
};
type B = {
    dataSource?: Date
};

const a: A = { dataSource: undefined }; // Error: Type 'undefined' is not assignable to type 'Date | null'.
const b: B = { dataSource: undefined }; // Works

Live Example in the Playground

like image 144
T.J. Crowder Avatar answered Nov 02 '22 08:11

T.J. Crowder


There is a big difference. The ? modifier is actually equivalent to | undefined.

These are entirely equivalent:

myVariable: FileSource | undefined;
mySecondVariable?: FileSource;
like image 29
Duncan Avatar answered Nov 02 '22 08:11

Duncan