当条件语句使用函数调用的结果而不是布尔表达式时,条件语句中类型推断的 TS 错误
TS Error with Type Inference within Conditional Statement, when the condtional is using the result of a function call instead of a boolean expression
我有以下用于链接列表 class 的 TypeScript class,一切正常。
type ListItem = number | string | object;
class Node {
private value: ListItem;
private next: Node | null;
constructor(value: ListItem) {
this.value = value;
this.next = null;
}
set nodeValue(value: ListItem) {
this.value = value;
}
set nextNode(next: Node | null) {
this.next = next;
}
get nodeValue(): ListItem {
return this.value;
}
get nextNode(): Node | null {
return this.next;
}
}
export class LinkedList {
private head: Node | null;
private tail: Node | null;
constructor(value: ListItem | null = null) {
// Case 1: Linked List is initialised with 1 argument
// Case 2: Linked List is initialised with null
if (value) {
const node = new Node(value);
this.head = node;
this.tail = node;
} else {
this.head = null;
this.tail = null;
}
}
public addLast(item: ListItem): void {
const newNode = new Node(item);
// Case 1 (if): Empty List
// Case 2 (else): Non Empty List
if (this.head === null || this.tail == null) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.nextNode = newNode;
this.tail = this.tail.nextNode;
}
}
public addFirst(item: ListItem): void {
const newNode = new Node(item);
// Case 1 (if): Empty List
// Case 2 (else): Non Empty List
if (this.head === null || this.tail === null) {
this.head = newNode;
this.tail = newNode;
} else {
newNode.nextNode = this.head;
this.head = newNode;
}
}
}
现在我想创建一个辅助函数 isEmpty() 来检查链表是否为空,如下所示。
private isEmpty(): boolean {
return this.head === null || this.tail === null;
}
然后按如下方式更改 addLast() 函数
public addLast(item: ListItem): void {
const newNode = new Node(item);
// Case 1 (if): Empty List
// Case 2 (else): Non Empty List
if (this.isEmpty()) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.nextNode = newNode; // error
this.tail = this.tail.nextNode; // error
}
}
但这会导致错误,这是有道理的,因为现在我猜 TS 不知道我的条件的执行情况,只有结果并且不知道 this.tail 或 this.head 不能再在 else 语句中为 null。有没有办法解决。我可以在没有 tsc 抱怨的情况下以某种方式使用我的助手吗?我想过也许使用某种类型的守卫,但想不出什么。我还是 TS 的新手,这可能吗,我是否错过了一些我可以做的明显的事情?或者助手不是一个可行的选择?
您可以使用 not null 或 undefined 断言运算符让编译器知道您现在知道 tail 已在该点赋值。
this.tail!.nextNode = newNode;
this.tail! = this.tail!.nextNode;
你可以了解更多here
我有以下用于链接列表 class 的 TypeScript class,一切正常。
type ListItem = number | string | object;
class Node {
private value: ListItem;
private next: Node | null;
constructor(value: ListItem) {
this.value = value;
this.next = null;
}
set nodeValue(value: ListItem) {
this.value = value;
}
set nextNode(next: Node | null) {
this.next = next;
}
get nodeValue(): ListItem {
return this.value;
}
get nextNode(): Node | null {
return this.next;
}
}
export class LinkedList {
private head: Node | null;
private tail: Node | null;
constructor(value: ListItem | null = null) {
// Case 1: Linked List is initialised with 1 argument
// Case 2: Linked List is initialised with null
if (value) {
const node = new Node(value);
this.head = node;
this.tail = node;
} else {
this.head = null;
this.tail = null;
}
}
public addLast(item: ListItem): void {
const newNode = new Node(item);
// Case 1 (if): Empty List
// Case 2 (else): Non Empty List
if (this.head === null || this.tail == null) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.nextNode = newNode;
this.tail = this.tail.nextNode;
}
}
public addFirst(item: ListItem): void {
const newNode = new Node(item);
// Case 1 (if): Empty List
// Case 2 (else): Non Empty List
if (this.head === null || this.tail === null) {
this.head = newNode;
this.tail = newNode;
} else {
newNode.nextNode = this.head;
this.head = newNode;
}
}
}
现在我想创建一个辅助函数 isEmpty() 来检查链表是否为空,如下所示。
private isEmpty(): boolean {
return this.head === null || this.tail === null;
}
然后按如下方式更改 addLast() 函数
public addLast(item: ListItem): void {
const newNode = new Node(item);
// Case 1 (if): Empty List
// Case 2 (else): Non Empty List
if (this.isEmpty()) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.nextNode = newNode; // error
this.tail = this.tail.nextNode; // error
}
}
但这会导致错误,这是有道理的,因为现在我猜 TS 不知道我的条件的执行情况,只有结果并且不知道 this.tail 或 this.head 不能再在 else 语句中为 null。有没有办法解决。我可以在没有 tsc 抱怨的情况下以某种方式使用我的助手吗?我想过也许使用某种类型的守卫,但想不出什么。我还是 TS 的新手,这可能吗,我是否错过了一些我可以做的明显的事情?或者助手不是一个可行的选择?
您可以使用 not null 或 undefined 断言运算符让编译器知道您现在知道 tail 已在该点赋值。
this.tail!.nextNode = newNode;
this.tail! = this.tail!.nextNode;
你可以了解更多here