我正试图围绕以下内容。我有一个功能:
export const useProject = (id: string) => {
<project fetching logic here>
return {
project,
loading: project === undefined
}
}
基本上,如果存在项目,则loading
为false,否则为project
未定义。
我的问题是使用以下代码:
const { project, loading } = useProject(id)
if (loading) return 'loading…'
return project.title
typescript抱怨project
在最终返回时可能是不确定的。在project
是loading
的情况下,如何更新函数以使打字稿知道false
存在?
答案 0 :(得分:2)
这里的主要问题是,即使您将useProject()
的返回值表示为discriminated union,其中loading
属性也可以用来确定project
属性定义后,一旦将子属性复制到单独的project
和loading
变量中,TypeScript编译器将无法遵循它们之间的相关性。
也就是说,您可以像这样优化useProject()
的类型:
export const useProject = (id: string) => {
const project = Math.random() < 0.5 ? ({ title: "hey" } as Project) : undefined;
return {
project,
loading: project === undefined
} as { project: Project, loading: false } | { project: undefined, loading: true };
}
,但以下代码仍会给您一个错误:
const { project, loading } = useProject("zoop")
if (loading) return 'loading…'
return project.title; // error! Object is possibly undefined
如果您想让编译器了解检查loading
对project
类型的影响,则需要将它们称为公共父区分联合对象的属性:>
const projStatus = useProject("zoop");
if (projStatus.loading) return 'loading…';
return projStatus.project.title; // okay
在GitHub中有一些未解决的问题,建议编译器应基于属性或其他类型保护检查(已复制到其他变量,例如microsoft/TypeScript#12184和{ {3}},但响应基本上是“ microsoft/TypeScript#24865”:
这将要求我们跟踪一个变量的特定值对其他变量的影响,这将给控制流分析仪增加很多复杂性(以及相关的性能损失)。尽管如此,我们仍将其作为建议。
因此,我不会等待解决此问题。如果您可以将代码重构为不破坏结构的有区别的联合,那就太好了。否则,您将需要使用that's probably too hard或等效命令来使编译器的警告静音:
return project!.title; // okay, using non-null assertion
好的,希望能有所帮助;祝你好运!