typescript - 带有类型谓词的参数的窄类型

标签 typescript

我对根据单个字段的类型缩小类型感兴趣。但是,TypeScript 似乎没有使用类型谓词来缩小类型中其他参数的类型,就像直接在 if 语句中使用基元运算符时那样。我能做些什么来让类型缩小在这里正常工作吗?

export function isTrue(input: boolean | undefined | null): input is true {
  return input === true;
}

type Refine =
  | {
      b: true;
      c: 'bIsTrue';
    }
  | {
      b: undefined;
      c: 'bIsUndefined';
    }
  | {
      b: false;
      c: 'bIsFalse';
    };

export function example() {
  const example = (null as unknown) as Refine;

  if (example.b === true) {
    example.b;  // Type is: true
    example.c;  // Type is: 'bIsTrue'
  }

  if (isTrue(example.b)) {
    example.b;  // Type is: true
    example.c;  // Type is: 'bIsTrue' | 'bIsUndefined' | 'bIsFalse'
  }
}

最佳答案

一种可能性是对整个对象执行缩小,然后访问它的属性:

function hasTrueBProperty<T extends { b: unknown }>(object: T): object is T & { b: true } {
  return object.b === true;
}

declare const refine: Refine;
if (hasTrueBProperty(refine)) {
  refine.b;  // Type is: true
  refine.c;  // Type is: 'bIsTrue'
}

要将属性作为参数传递给测试,请使用另一个泛型:

function hasTrueProperty<P extends PropertyKey, T extends Record<P, unknown>>(object: T, prop: P): object is T & Record<P, true> {
  return object[prop] === true;
}

declare const refine: Refine;
if (hasTrueProperty(refine, 'b')) {
  refine.b;  // Type is: true
  refine.c;  // Type is: 'bIsTrue'
}

关于typescript - 带有类型谓词的参数的窄类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73159061/

相关文章:

javascript - 如何使用 sequelize 和 sqlite 验证 int 和 boolean

typescript - 当 TypeScript 阻止我时,如何将 testId 属性添加到用于测试库的 React Native 组件?

javascript - 使用 React + TypeScript,在启用 strictNullChecks 的情况下使用默认值的可选 Prop 时如何避免类型转换?

javascript - ReactJS + Typescript 中的条件 setInterval 和clearInterval

typescript - 我可以编写断言多个不变量的类型保护吗?

javascript - Angular 2 - 通过类属性在 View 中显示来自事件监听器函数的值

javascript - 向 Jest 添加模块映射器?

javascript - webpack 创建的脚本执行两次

javascript - Angular2/Typescript/ngRx - 类型错误 : Cannot assign to read only property of object

image - 在 TypeScript 中设置图像源