在 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) {
// ...
},
});
让我们有以下代码:
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 = ...
.
是否可以改进接口以便推断 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) {
// ...
},
});