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
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.
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.
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 .
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.
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
There is a big difference. The ?
modifier is actually equivalent to | undefined
.
These are entirely equivalent:
myVariable: FileSource | undefined;
mySecondVariable?: FileSource;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With