[英]Why is TypeScript showing “Cannot invoke an object which is possibly 'undefined'.ts(2722)” error after optional chaining operator?
During this stayhome period I decided to dive into TypeScript and started to practice it by implementing some basic data structures.在这段宅家期间,我决定深入研究 TypeScript 并开始通过实现一些基本数据结构来实践它。 I am trying to implement a custom stack that uses custom nodes.
我正在尝试实现一个使用自定义节点的自定义堆栈。
My StackNodes are defined like this:我的 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;
And the actual Stack:而实际的堆栈:
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;
The problem here is the line with the optional chaining operator in pop-method this.top = this.top?.next()
这里的问题是弹出方法
this.top = this.top?.next()
中的可选链接运算符的行
What I have understood is that the expression this.top?.next()
should be equivalent to我所理解的是表达式
this.top?.next()
应该等同于
(this.top === null || this.top === undefined)? undefined: this.top.next()
but I still get the error但我仍然收到错误
Cannot invoke an object which is possibly 'undefined'.ts(2722)
无法调用可能是“未定义”的 object.ts(2722)
when the call is made even though it shouldn't be undefined anymore at that stage.即使在那个阶段它不应该是未定义的,也可以在进行调用时。
Why's that?为什么? What am I missing here?
我在这里想念什么? Both the StackNode.nxt and Stack.top are allowed to be undefined.
StackNode.nxt 和 Stack.top 都允许未定义。 I have tried to do it in the old way like this:
我试图以这样的旧方式做到这一点:
if (this.top !== null || this.top !== undefined) {
const value = this.top.value()
this.top = this.top.next()
}
But I still get the same error, even though here it should be sure that the this.top
can not be undefined, but has to be, or at least should be, of type StackNode.但是我仍然遇到同样的错误,即使在这里应该确保
this.top
不能未定义,但必须或至少应该是 StackNode 类型。
How this should work is that when popping from empty stack, pop method would return undefined and when popping the last element, its next, that is undefined, is set as the top of the stack.这应该是如何工作的,当从空堆栈弹出时,pop 方法将返回 undefined 并且当弹出最后一个元素时,它的下一个未定义的元素被设置为堆栈的顶部。
I am using TS 3.8.3我正在使用 TS 3.8.3
You define next as a getter, so it must be accessed like so: this.top = this.top?.next
您将 next 定义为 getter,因此必须像这样访问它:
this.top = this.top?.next
The only reason that const value = this.top?.value();
const value = this.top?.value();
的唯一原因even compiles is because you use 'any' (DONT DO THAT, EVER,!), and typescript assumes that get value
might return a function that you are invoking.甚至编译是因为您使用“任何”(永远不要这样做,永远!),并且 typescript 假设
get value
可能会返回您正在调用的 function。
You should define StackNode using generics.您应该使用 generics 定义 StackNode。 For example,
例如,
class StackNode<T> {
private val: T;
private nxt: StackNode<T> | undefined = undefined;
constructor(val: T, nxt?: StackNode<T> | undefined) {
this.val = val;
this.nxt = nxt || undefined;
}
get value(): T {
return this.value;
}
get next(): StackNode<T> {
return this.next;
}
}
class Stack<T> {
private capacity!: number;
private top?: StackNode<T> | 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<T> => {
if (idx == 0) {
return new StackNode(array[idx], undefined);
} else {
return new StackNode(array[idx], this._initStack(array, idx-1));
}
}
pop(): T | undefined {
const value = this.top?.value(); //doesn't compile
this.top = this.top?.next(); //doesn't compile either
return value;
}
}
Then, const value = this.top?.value();
然后,
const value = this.top?.value();
would not have compiled either.也不会编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.