让我们输入以下代码:
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) {
// ...
},
};
现在,我认为在ActionA
中指定类型实参const processorA: Processor<ActionA> = ...
是多余的,因为可以从action: ActionA
推断出来。不幸的是,如果我只写const processorA: Processor = ...
,打字稿就会报错。
是否可以改进接口,以便推断出Processor
的类型实参?
高级版本:
我还希望action
字段的类型为T | '*'
。在那种情况下,action
的{{1}}参数应该是process(action)
类型(或者在最坏的情况下,只是Action
)。可以与上述类型参数推断一起使用吗?
答案 0 :(得分:3)
打字稿中无法推断变量类型的一部分。对于变量推论是全有还是全无,您要么让编译器进行推论,要么在类型注释中指定它。
您可以使用函数来推断操作的类型:
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) {
// ...
},
});