在 TypeScript 中推断接口类型参数

Infer interface type argument in TypeScript

让我们有以下代码:

interface Action {
  type: string;
}

interface ActionA extends Action {
  type: 'A';
  payload: number;
}

interface ActionB extends Action {
  type: 'B';
  payload: string;
}

interface Processor<T extends Action> {
  action: T;
  process: (action: T) => void;
}

// usage

const actionA: ActionA = { type: 'A', payload: 42 };

const processorA: Processor<ActionA> = {
  action: actionA,
  process(action) {
    // ...
  },
};

现在我认为在 const processorA: Processor<ActionA> = ... 中指定类型参数 ActionA 是多余的,因为它可以从 action: ActionA 中推断出来。不幸的是,如果我只写 const processorA: Processor = ....

,Typescript 会报告错误

是否可以改进接口以便推断 Processor 的类型参数?

高级版:

我还希望 action 字段的类型为 T | '*'。在那种情况下,process(action)action 参数应该是 Action 类型(或者在最坏的情况下只是 any)。这是否可以与上述类型参数推断一起使用?

打字稿无法推断变量类型的一部分。对于变量推断是全有或全无,您要么让编译器推断它,要么在类型注释中指定它。

您可以使用函数来推断操作的类型:

function createProcessor<T extends Action>(p: Processor<T>) {
    return p
}
const processorA = createProcessor({
  action: actionA,
  process(action) {
    // ...
  },
});

或者您可以使用 IIFE 作为一种奇特的类型断言:

const processorA = (<T extends Action>(p: Processor<T>) => p)({
  action: actionA,
  process(action) {
    // ...
  },
});