类型缩小与控制流分析托架元素访问已为用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;
});发布于 2022-06-22 18:08:48
这些改进工作在string literals和symbols上。这意味着,当键是变量时,它将无法工作,因此出现了问题。
您可以使用类型谓词来修复这个问题,但是您将无法为该变量赋值。
这里有一个游乐场,它展示了这一点。
https://stackoverflow.com/questions/72720001
复制相似问题