[英]An object is created without a method of a class. Typescript error: Cannot invoke an object which is possibly 'undefined'. ts(2722)
[英]Why is TypeScript showing “Cannot invoke an object which is possibly 'undefined'.ts(2722)” error after optional chaining operator?
在這段宅家期間,我決定深入研究 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;
這里的問題是彈出方法this.top = this.top?.next()
中的可選鏈接運算符的行
我所理解的是表達式this.top?.next()
應該等同於
(this.top === null || this.top === undefined)? undefined: this.top.next()
但我仍然收到錯誤
無法調用可能是“未定義”的 object.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
您將 next 定義為 getter,因此必須像這樣訪問它: this.top = this.top?.next
const value = this.top?.value();
的唯一原因甚至編譯是因為您使用“任何”(永遠不要這樣做,永遠!),並且 typescript 假設get value
可能會返回您正在調用的 function。
您應該使用 generics 定義 StackNode。 例如,
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;
}
}
然后, const value = this.top?.value();
也不會編譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.