網站搜尋

使用泛型類型時,TypeScript 類型縮小無法正常工作


在 Typescript 3.8(Angular 9 前端)中,下面的代碼類型縮小似乎不起作用。我嘗試了一些實驗,但沒有進展。

  • 我認為這與我錯誤使用 enum 無關,而是涉及在 TypeScript 中擴展泛型的一些複雜性。
  • 也許如果我想讓程式碼縮小類型有效,但我使用了錯誤的方式來定義介面?

有人可以給我一個提示嗎?

請參考下方或 StackBkitz 代碼以查看我的情況

export enum DetailType {
  A = 'A',
  B = 'B',
  C = 'C',
}

interface D1 {
  type: DetailType.A;
}

interface D2 {
  type: DetailType.B;
}

interface D3 {
  type: DetailType.C;
}

type Detail = D1 | D2 | D3;


type SystemFinding<detailType extends Detail> = {
  detail: detailType;
};

interface Finding<detailType extends Detail> extends SystemFinding<detailType> {
  findingUid?: string;
}


type FindingSummary<T extends Detail> = {
  prop1: string;
  prop2: Finding<T>;
};


function runA(st: FindingSummary<D1>) {
  console.log(st);
}

function runB(st: FindingSummary<D2>) {
  console.log(st);
}

function runC(st: FindingSummary<D3>) {
  console.log(st);
}

function runTool(findingSummary: FindingSummary<Detail>) {
  switch (findingSummary.prop2.detail.type) {
    case DetailType.A:
      findingSummary; // type is findingSummary: FindingSummary<Detail>, type narrowing isn't working?
      runA(findingSummary);
      break;
    case DetailType.C:
      findingSummary;
      runB(findingSummary);
      break;
    case DetailType.C:
      findingSummary;
      runB(findingSummary);
      break;
    default:
  }
}

答案#1

暫時,我必須使用類型轉換。但我希望我不需要這麼做。

function runTool(findingSummary: findingSummary<Detail>) {
  switch (findingSummary.prop2.detail.type) {
    case DetailType.A:
      const a1: findingSummary<D1> = <findingSummary<D1>>findingSummary;
      runA(a1);
      break;
    case DetailType.B:
      const a2: findingSummary<D2> = <findingSummary<D2>>findingSummary; 
      runB(a2);
      break;
    case DetailType.C:
      const a3: findingSummary<D3> = <findingSummary<D3>>findingSummary; 
      runC(a3);
      break;
    default:
  }
}