TypeScript 建议:基于用户定义的类型保护,实现类型缩小

72qzrwbm  于 3个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(43)

搜索词

用户自定义类型保护、类型 predicate 、类型缩小、对象属性

建议

TS可以通过各种方式在if语句和其他条件控制流中缩小对象类型。特别是,如果对象的类型是一个可以通过“标签”(如下面的示例中的Option<T>)区分的联合类型,我们可以通过检查标签的值来缩小类型。然而,如果对标签的检查是通过用户定义的类型保护针对属性(而不是对象本身)进行的,那么对象的类型就不会缩小。
建议即使应用了用户定义的类型保护到对象属性上也能使其正常工作。

使用案例

“标记联合”模式在TS代码库中广泛使用。如果标签本身很复杂,我们希望利用用户定义的类型保护来检查它们。

示例

type Option<T> = {
  type: "some"
  value: T
} | {
  type: "none"
}

const isSome = (type: "some" | "none"): type is "some" => type === "some"

declare const option: Option<number>

// Good: option is narrowed in the if block
if (option.type === "some") {
  option.value
}

// Bad: option isn't narrowed
if (isSome(option.type)) {
  // Error: Property 'value' does not exist on type 'Option<number>'.
  option.value
}

// Available workaround
const isSomeObject = <T>(option: Option<T>): option is Extract<Option<T>, { type: "some" }> => option.type === "some"

if (isSomeObject(option)) {
  option.value
}

playground

检查清单

我的建议满足以下指导原则:

  • 这不会在现有的TypeScript/JavaScript代码中造成破坏性的变化
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不根据表达式的类型发出不同的JS的情况下实现
  • 这不是一个运行时特性(例如库功能、带有JavaScript输出的非ECMAScript语法等)
  • 这个特性将与TypeScript's Design Goals的其他部分保持一致。
snz8szmq

snz8szmq1#

我最近遇到了一个错误,以下代码片段出现了问题:

function check_object(o: { a?: string }): { a: string } {
  if (!o.a) throw new Error("Invalid object");
  return o;
}

(TypeScript没有缩小o的类型)
这个提案是否能修复这个错误?

cx6n0qe3

cx6n0qe32#

很遗憾,这个建议不会影响你的使用案例。
或许这些问题是相关的:#33205(评论),#30506,#31755

相关问题