Skip to content

Commit 8d4c016

Browse files
committed
improve TS
1 parent dddcbd1 commit 8d4c016

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

src/utils.ts

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -897,9 +897,18 @@ export function deepCopy<T>(value: T): T {
897897
return value;
898898
}
899899

900-
/** @internal */
901-
type ListNode<T> = { value: T; next: ListNode<T>; prev: ListNode<T> };
902-
type HeadNode<T> = { value: null; next: ListNode<T>; prev: ListNode<T> };
900+
type ListNode<T> = {
901+
value: T;
902+
next: ListNode<T> | HeadNode<T>;
903+
prev: ListNode<T> | HeadNode<T>;
904+
};
905+
906+
type HeadNode<T> = {
907+
value: null;
908+
next: ListNode<T> | HeadNode<T>;
909+
prev: ListNode<T> | HeadNode<T>;
910+
};
911+
903912
/**
904913
* A sequential list of items in a circularly linked list
905914
* @remarks
@@ -924,13 +933,16 @@ export class List<T = unknown> {
924933
constructor() {
925934
this.count = 0;
926935

936+
// this is carefully crafted:
937+
// declaring a complete and consistently key ordered
938+
// object is beneficial to the runtime optimizations
927939
this.head = {
928-
next: null as unknown as ListNode<T>,
929-
prev: null as unknown as ListNode<T>,
940+
next: null as unknown as HeadNode<T>,
941+
prev: null as unknown as HeadNode<T>,
930942
value: null
931943
};
932-
this.head.next = this.head as unknown as ListNode<T>;
933-
this.head.prev = this.head as unknown as ListNode<T>;
944+
this.head.next = this.head;
945+
this.head.prev = this.head;
934946
}
935947

936948
toArray() {
@@ -947,12 +959,12 @@ export class List<T = unknown> {
947959
}
948960
}
949961

950-
private *nodes() {
951-
let ptr = this.head.next;
962+
private *nodes(): Generator<ListNode<T>, void, void> {
963+
let ptr: HeadNode<T> | ListNode<T> = this.head.next;
952964
while (ptr !== this.head) {
953965
// Save next before yielding so that we make removing within iteration safe
954966
const { next } = ptr;
955-
yield ptr;
967+
yield ptr as ListNode<T>;
956968
ptr = next;
957969
}
958970
}
@@ -961,7 +973,7 @@ export class List<T = unknown> {
961973
push(value: T) {
962974
this.count += 1;
963975
const newNode: ListNode<T> = {
964-
next: this.head as ListNode<T>,
976+
next: this.head,
965977
prev: this.head.prev,
966978
value
967979
};
@@ -981,15 +993,15 @@ export class List<T = unknown> {
981993
this.count += 1;
982994
const newNode: ListNode<T> = {
983995
next: this.head.next,
984-
prev: this.head as ListNode<T>,
996+
prev: this.head,
985997
value
986998
};
987999
this.head.next.prev = newNode;
9881000
this.head.next = newNode;
9891001
}
9901002

991-
private remove(node?: ListNode<T> | null): T | null {
992-
if (node == null || this.length === 0) {
1003+
private remove(node?: ListNode<T> | HeadNode<T> | null): T | null {
1004+
if (node == null || node === this.head || this.length === 0) {
9931005
return null;
9941006
}
9951007

@@ -1024,8 +1036,8 @@ export class List<T = unknown> {
10241036

10251037
clear() {
10261038
this.count = 0;
1027-
this.head.next = this.head as ListNode<T>;
1028-
this.head.prev = this.head as ListNode<T>;
1039+
this.head.next = this.head;
1040+
this.head.prev = this.head;
10291041
}
10301042

10311043
/** Returns the first item in the list, does not remove */

0 commit comments

Comments
 (0)