简体   繁体   English

难以理解 Typescript 中类型谓词的使用

[英]Having difficulty understanding the use of Type predicate in Typescript

I am new to TypeScript and was reading about Type Narrowing and Type Guards.我是 TypeScript 的新手,并且正在阅读有关 Type Narrowing 和 Type Guards 的信息。 I came across the following code where the typescript compiler shows an error and the author solves it using type predicates.我遇到了以下代码,其中 typescript 编译器显示错误,作者使用类型谓词解决了它。 https://dev.to/smeijer/typescript-type-guards-and-type-predicates-4m5e For example, https://dev.to/smeijer/typescript-type-guards-and-type-predicates-4m5e例如,

type Article = {
  frontMatter: Record<string, unknown>;
  content: string;
}

type NotFound = { 
  notFound: true;
}

type Page = Article | NotFound;

function handleRequest(slug: string): string {
  const article = db.articles.findOne({ slug });
  const page = article ?? { notFound: true };
  return render(page);
}

function render(page: Page) {
  if (page.content) { -------> Typescript showing Error
    return page.content; -----> Typescript showing Error
  }

  return '404 — not found';
}

As you can see, inside the render function, typescript compiler showing error saying that如您所见,在渲染 function、typescript 编译器内部显示错误说

Property 'content' does not exist on type 'Page'.
  Property 'content' does not exist on type 'NotFound'

My question is, inside the if block, I already know the content exists as a property of page , then why it is showing error and why using predicate solves the issue like following.我的问题是,在if块中,我已经知道content作为page的属性存在,那么为什么它显示错误以及为什么使用谓词可以解决如下问题。

function isArticle(page: Page): page is Article {
  return typeof (page as Article).content !== 'undefined';
}

function render(page: Page) {
  if (isArticle(page)) {
    return page.content;
  }

  return '404 — not found';
}

Thanks in advance for your help.在此先感谢您的帮助。

if (page.content) { -------> Typescript showing Error

Typescript is set up to not let you access properties unless they definitely exist. Typescript 设置为不允许您访问属性,除非它们确实存在。 So, as you know, this line is an error.所以,如你所知,这条线是一个错误。

My question is, inside the if block, I already know the content exists as a property of page, then why it is showing error and why using predicate solves the issue like following.我的问题是,在 if 块中,我已经知道内容作为页面的属性存在,那么为什么它显示错误以及为什么使用谓词可以解决如下问题。

You may know that, but typescript does not.您可能知道,但 typescript 不知道。 When typescript encountered the error on the first line, it aborted any logic to try to narrow down the types.当 typescript 在第一行遇到错误时,它中止了任何逻辑以尝试缩小类型。 Typescript is basically waiting for you to fix the error. Typescript 基本上就是等你修复错误了。 Until you do, typescript will not narrow the type, which means page is viewed as a Article | NotFound在您这样做之前,typescript 不会缩小类型,这意味着page被视为Article | NotFound Article | NotFound , and thus it's still illegal to access page.content . Article | NotFound ,因此访问page.content仍然是非法的。

The custom type guard you wrote is one possible way to fix the error, but you could also check whether page.content exists without accessing it, via the in operator:您编写的自定义类型保护是修复错误的一种可能方法,但您也可以通过in运算符检查 page.content 是否存在而不访问它:

if ('content' in page) {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM