我有以下一段代码:

class Gateway {}
class GatewayA extends Gateway { open() {} }
class GatewayB extends Gateway { }

type UseCase<T> = (...gateways: Gateway[]) => () => Promise<T>;

const gatewayA = new GatewayA;
const gatewayB = new GatewayB;

const fooUseCase: UseCase<boolean> = (gatewayA: GatewayA, gatewayB: GatewayB) => async () => {
  console.log(gatewayA);
  console.log(gatewayB);
  return true;
};

fooUseCase(gatewayA, gatewayB);

Gateways继承自Gateway基类,可能会添加新方法.此外,用例可以有不同的网关参数,例如,这意味着fooUseCase需要GatewayAGatewayB,但barUseCase可能需要GatewayC.

但TS抛出了这个错误:

Type '(gatewayA: GatewayA, gatewayB: GatewayB) => () => Promise<true>' is not assignable to type 'UseCase<boolean>'.
  Types of parameters 'gatewayA' and 'gateways' are incompatible.
    Property 'open' is missing in type 'Gateway' but required in type 'GatewayA'.ts(2322)

在不知道网关的哪些实现将作为参数传递的情况下,我如何定义UseCase类型?

谢谢.

推荐答案

原因是UseCase被设计为在任何网关上工作,而实例fooUseCase"强制"通过特定的GatewayA.

让我们想象一个需要UseCase作为参数的函数doSomeJob.假设此函数只有2个网关B可以提供给此用例.根据合同,它应该行得通.但它将不能在fooUseCase中正确调用:

doSomeJob(fooUseCase);

function doSomeJob(useCase: UseCase<boolean>) {
    useCase(new GatewayB(), new GatewayB())
}

您可以使用参数化类型解决此问题:

type UseCase<G1 extends Gateway, G2 extends Gateway, T> = (gatewayA: G1, gatewayB: G2) => () => Promise<T>;

const fooUseCase: UseCase<GatewayA, GatewayB, boolean> = (gatewayA: GatewayA, gatewayB: GatewayB) => async () => { ... }

Typescript相关问答推荐

TypScript ' NoInfer '类型未按预期工作

typescribe不能使用值来索引对象类型,该对象类型满足具有该值的另一个类型'

如何推断哪个特定密钥与泛型匹配?

TypeScript:在作为参数传递给另一个函数的记录中对函数的参数实现类型约束

是否使用非显式名称隔离在对象属性上声明的接口的内部类型?

在实现自定义主题后,Angular 不会更新视图

使用订阅时更新AG网格中的行

使用数组作为类型中允许的键的列表

如何编写在返回函数上分配了属性的类型安全泛型闭包

复选框Angular 在Ngfor中的其他块中重复

与toast.error一起react 中的Async TUNK错误消息

map 未显示控制台未显示任何错误@reaction-google-map/api

TS不能自己推断函数返回类型

如何正确键入泛型相对记录值类型?

React中的效果挂钩在依赖项更新后不会重新执行

如何从联合类型推断函数参数?

如何通过nx找到所有受影响的项目?

Typescript 和 Rust 中跨平台的位移数字不一致

覆盖高阶组件中的 prop 时的泛型推理

是否可以使用元组中对象的键来映射类型