簡體   English   中英

通過括號元素訪問的控制流分析將對象字段的類型縮小為類型數組

[英]Narrow down type of object field to type array via control-flow analysis for bracketed element access

TypeScript 4.7 改進了對括號元素訪問進行控制流分析的類型縮小。

我還想做的是檢查訪問的字段是否是數組。 現在,我不知道為什么類型保護不起作用:

Error: Type 'never[]' is not assignable to type 'string'.(2322)

在此處輸入圖像描述

正如您在占位符注釋中看到的那樣,TypeScript 仍然認為訪問的字段可能是string類型,盡管isArray應該明確指出該字段是某種數組。

我錯過了什么?


這是一個完整的例子:

假設我們有一個Post類型,其中一些字段是數組:

type Post = {
  id: string;
  title: string;
  chapters: PostChapter[];
};

現在,我有字符串列表( Post的鍵),我想用它來動態覆蓋Post對象中的值:

const fieldNamesToReplace: (keyof Post)[] = ["chapters"];

當使用帶有括號訪問的鍵時,TypeScript 不知道它是一個數組,即使您通過Array.isArray檢查它也是如此。

順便說一句:什么有效(作為一種解決方法?)只是創建一個新對象並覆蓋該字段,因為我們不依賴於括號訪問的控制分析。


這是一個游樂場鏈接和完整示例:

游樂場鏈接

type PostChapter = {
  id: string;
  chapterTitle: string;
};

type Post = {
  id: string;
  title: string;
  chapters: PostChapter[];
};

const fieldNamesToReplace: (keyof Post)[] = ["chapters"];

const posts: Post[] = [
  {
    id: "1",
    title: "abc",
    chapters: [{ id: "1.1", chapterTitle: "def" }],
  },
];

const postsTransformed = posts.map((post) => {
  let postNew = { ...post };

  // works, because we don't rely on the type-narrowing for setting the value
  fieldNamesToReplace.forEach((fieldName) => {
    if (Array.isArray(postNew[fieldName])) {
      postNew = { ...postNew, [fieldName]: [] };
    }
  });

  // doesn't work
  fieldNamesToReplace.forEach((fieldName) => {
    if (Array.isArray(postNew[fieldName])) {
      postNew[fieldName] = [];
      // Error: Type 'never[]' is not assignable to type 'string'.(2322)

      const placeholder = postNew[fieldName];
      //      ^?
    }
  });

  return postNew;
});


這些改進適用於string literalssymbols 這意味着當鍵是變量時它將不起作用,因此您的問題。

您可以使用類型謂詞來解決此問題,但您將無法分配給該變量。

這是一個展示這一點的游樂場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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