簡體   English   中英

為什么 TypeScript 在可選鏈接運算符后顯示“無法調用 object 這可能是'未定義'.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM