在这段居家期间,我决定深入研究 TypeScript,并开始通过实现一些基本的数据结构来实践它。我正在尝试实现一个使用自定义节点的自定义堆栈。
我的 StackNode 定义如下:
class StackNode {
private val: any;
private nxt: StackNode | undefined = undefined;
constructor(val: any, nxt?: StackNode | undefined) {
this.val = val;
this.nxt = nxt || undefined;
}
get value(): any {
return this.value;
}
get next(): StackNode | undefined {
return this.next;
}
}
export default StackNode;
和实际的堆栈:
class Stack {
private capacity!: number;
private top?: StackNode | undefined = undefined;
private size: number = 0;
constructor(capacity: number, initialValues?: Array<any>) {
this.capacity = capacity;
if (initialValues) {
this.size = initialValues.length;
this.top = this._initStack(initialValues, initialValues.length - 1);
}
};
private _initStack = (array: Array<any>, idx: number): StackNode => {
if (idx == 0) {
return new StackNode(array[idx], undefined);
} else {
return new StackNode(array[idx], this._initStack(array, idx-1));
}
}
pop(): any {
const value = this.top?.value();
this.top = this.top?.next();
return value;
}
}
export default Stack;
这里的问题是pop-method 中可选链接运算符的行this.top = this.top?.next()
我的理解是表达式this.top?.next()
应该等同于
(this.top === null || this.top === undefined)? undefined : this.top.next()
但我仍然收到错误
无法调用可能是“未定义”的对象。ts(2722)
即使在那个阶段它不应该是未定义的,也可以在进行调用时。
为什么?我在这里想念什么?StackNode.nxt 和 Stack.top 都允许未定义。我试图以这样的旧方式做到这一点:
if (this.top !== null || this.top !== undefined) {
const value = this.top.value()
this.top = this.top.next()
}
但我仍然得到同样的错误,即使在这里应该确保this.top
不能未定义,但必须或至少应该是 StackNode 类型。
这应该是如何工作的,当从空堆栈弹出时,pop 方法将返回 undefined 并且当弹出最后一个元素时,它的下一个未定义的元素被设置为堆栈的顶部。
我正在使用 TS 3.8.3