在下面的代码中,我有一个名为isLegacyPayment的类型.然而,尽管使用了它,并且在期望字符串const stripeId: string = payment.stripeId的行之前返回或抛出,它仍然认为payment.stripeId可能为空.我试图让这个类型的GUGID工作,因为这个GUGID的反义词(判断它的字符串是否有效)与其他DEVisNotLegacyPayment相比有一个非常令人困惑的名字.任何与isNot有关的数字都会引起重大混乱.有没有可能让isLegacyPayment人在下面工作?

The error we see is: enter image description here

以下是-https://www.typescriptlang.org/play?#code/C4TwDgpgBACghiAthAdsKBeKBvAUFKAZ2ACcBLSASQBMAuKFAVwBtmoAfI0slAcwG5cAX1wAzRigDGwMgHsUUMoQAyEXnEkh4SVMAA8AFSgQAHsFTVCsMpIDWe7cjQAaKAHJi5KtTcA+XwAUYAhOwPQGAJT0wTpoilZGAGQ4XF4QNPRMrFBCOPhQJBDAjCQKMaEAdJ4U6dSYGFhZzIIiuGIS0nIK5sQBEXkEkvLEUOW69I66mCnV3vRuAIwATADMSwtuOYL5ZKJQAUqq6pqTaEEhuhH9eAQEwAAWJLIA7gwQrwCiJE8kAW6UVmYag0IFGFzQbgiggIrUGw3Qs1q9GqfGmYzQVW43m2QiAA以下代码的打字脚本

type Payment = {
  stripeId: null | string;
}

function isLegacyPayment<T extends Pick<Payment, 'stripeId'>>(payment: T): payment is T & { stripeId: null } {
  return payment.stripeId === null;
}


function test() {
  const payment: Payment = { stripeId: '12321' };

  if (isLegacyPayment(payment)) {
    throw new Error('Is legacy payment');
  }

  const stripeId: string = payment.stripeId; // The error is here it says "Type 'string | null' is not assignable to type 'string'. Type 'null' is not assignable to type 'string'.(2322)

}

推荐答案

可以让isLegacyPayment在下面工作吗?

这是一个棘手的问题,我认为问题主要是因为&是类型的交集(组合),而|是联合(替代),所以代码有点倒退……

下面是我如何使它工作的,但是1)我不得不引入一些新类型,2)现在在if分支中,payment的类型是never;所以这可能不适合你的场景:

type Payment = {
  stripeId: null | string;
}

type LegacyPayment = Payment & {
  stripeId: null;
}

type CurrentPayment = Payment & {
  stripeId: string;
}

type NewPayment = LegacyPayment | CurrentPayment;

function isLegacyPayment(payment: NewPayment): payment is LegacyPayment {
  return payment.stripeId === null;
}

function test() {
  const payment: NewPayment = { stripeId: '12321' };

  //if (payment.stripeId === null) {  // this works too
  if (isLegacyPayment(payment)) {
    payment;  // const payment: never  (!!)

    throw new Error('Is legacy payment');
  }

  payment;           // const payment: CurrentPayment
  payment.stripeId;  // (property) stripeId: string

}

Link to playground

Typescript相关问答推荐

在NextJS中获得Spotify Oauth,但不工作'

泛型类型,引用其具有不同类型的属性之一

分解对象时出现打字错误

有没有可能为这样的函数写一个类型?

如何使所有可选字段在打印脚本中都是必填字段,但不能多或少?

MatTool提示在角垫工作台中不起作用

如果数组使用Reaction-Hook-Form更改,则重新呈现表单

在排版修饰器中推断方法响应类型

如何将别名添加到vitest配置文件?

常量类型参数回退类型

我在Angular 17中的environment.ts文件中得到了一个属性端点错误

如何在本地存储中声明该类型?

有没有办法在Reaction组件中动态导入打字脚本`type`?

使用&reaction测试库&如何使用提供程序包装我的所有测试组件

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

无法使用prisma中的事务更新记录

在Typescript 无法正常工作的 Three.js 中更新动画中的 GLSL 统一变量

React HashRouter,单击导航栏时页面重新加载出现问题

React router - 如何处理嵌套路由?

具有来自其他类型的修改键名称的 TypeScript 通用类型