【问题标题】:Type guard removing string literal types类型保护删除字符串文字类型
【发布时间】:2022-08-09 23:40:52
【问题描述】:

创建 TS 类型保护时,一旦将 undefinednull 添加到谓词类型,似乎字符串文字就会从缩小的类型中删除。有没有办法使用具有x is \'my-string\' | undefined 之类的谓词的类型保护?

或者,换句话说:假设我们有一个带有谓词x is \'my-string\' 的类型保护。每当使用此保护检查变量时,TS 都会正确地将传递的变量缩小为文字类型\'my-string\'。但是,一旦将谓词更改为x is \'my-string\' | undefined,TS 会将检查变量的类型缩小为undefined。我希望它是\'my-string\' | undefined。这是为什么?类型保护不是要检查字符串文字吗?

例子: Open in TS Playground

/*
  When using \"typeGuard1\", you will notice that the guarded type, for some reason, gets narrowed down to `undefined`.
  It works fine with \"typeGuard2\".
*/
function typeGuard1(x: any): x is \'some-literal-string-type\' | undefined {
  return true;
}
function typeGuard2(x: any): x is string | undefined {
  return true;
}

// The following setup is used to make sure the compiler does not magically infer anything.
const foo = getFoo();
function getFoo(): string | undefined {
  if (Math.random() > 0.5) {
    return \'This is foo\'
  }
  return undefined;
}

if (typeGuard1(foo)) {
  // For some reason, `foo` gets narrowed down to `undefined`. This does not happen if you use `isFoo2(foo)`, or if you remove \"| undefined\" from \"typeGuard1\".
  console.log(foo?.length);
}
if (typeGuard2(foo)) {
  console.log(foo?.length);
}
  • 行为很奇怪......似乎删除 undefined 有效:typescriptlang.org/play?ts=4.7.4#code/… 似乎是一个错误
  • @isaactfa 但是 TS 能够将字符串缩小为文字。示例:Playground 在这种情况下为什么不缩小类型?
  • @isaactfa 另外,为什么从警卫的谓词中删除 undefined 后它会按预期工作?
  • 嗯,确实很奇怪……

标签: typescript


【解决方案1】:

这是一个已知的错误,请参阅microsoft/TypeScript#31156。它已在 microsoft/TypeScript#49625 中修复,应该与 TypeScript 4.8 一起发布。一旦发生这种情况,您的代码将按预期工作:

Playground link to code using TS version 4.8.0-dev.20220809

【讨论】:

    猜你喜欢
    • 2021-07-17
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 2021-08-22
    • 2021-08-10
    相关资源
    最近更新 更多