I'm learning typescript, type safety (defensive programming), and i'm trying to implement a linked list with typescript.
I don't understand why when I change the logical OR (||) to logical AND (&&) on if (!this.head || !this.tail)
line, typescript throws an error on
const oldTail: NodeItem = this.tail;
that:
Type 'NodeItem | null' is not assignable to type 'NodeItem'. Type 'null' is not assignable to type 'NodeItem'.
Main block:
add(value: any): NodeItem {
const newItem: NodeItem = { value: value, next: null };
if (!this.head || !this.tail) {
this.head = newItem;
this.tail = this.head;
this.total++;
return newItem;
}
const oldTail: NodeItem = this.tail;
this.tail = newItem;
oldTail.next = this.tail;
this.total = this.total++;
return newItem;
}
Entire code for context:
type NodeItem = {
value: any;
next: NodeItem | null;
};
class LinkedList {
head: NodeItem | null = null;
tail: NodeItem | null = null;
total: number;
constructor(value?: any) {
value && this.add(value);
}
add(value: any): NodeItem {
const newItem: NodeItem = { value: value, next: null };
if (!this.head || !this.tail) {
this.head = newItem;
this.tail = this.head;
this.total++;
return newItem;
}
const oldTail: NodeItem = this.tail;
this.tail = newItem;
oldTail.next = this.tail;
this.total = this.total++;
return newItem;
}
print(): void {}
}
It's because after you change the logical OR (||) to logical AND (&&) on the if (!this.head || !this.tail)
line, the if block is not executed.
this.tail is null, so !this.tail is false. Which means, for logical OR, the if block will be executed, changing this.tail's value to this.head's, and ensuring the error does not occur. But, for logical AND, the false means the block will not be executed, and so this.tail remains null, giving you the error.
Hope this was easy to understand!