Два подхода для вас:
- С вашим типом
Call
в качестве типа перегруженной функции - С просто перегруженной функцией.
С вашим Call
типом
Тип, который вы хотите для Call
, является перегруженным типом функции. Вы можете определить это так:
type Call = {
(...args: ['add', number, number]): Promise<number>;
(...args: ['log', string]): Promise<void>;
};
Поскольку вам необходимо связать тип возвращаемого значения со списком параметров, тип Actions
на самом деле не помогает.
Функция, набранная с помощью этот тип будет делать вывод, который вы просили:
function doSomething(fn: Call) {
fn('add', 1, 2)
.then(value => {
// Here, TypeScript infers `value` is of type `number`
});
fn('log', 'message')
.then(value => {
// Here, TypeScript infers `avlue` is of type `void`
});
}
На игровой площадке
Если вы собираетесь писать для этого функции, это может помочь иметь несколько типов помощников:
type AddParams = ['add', number, number];
type LogParams = ['log', string];
type ActionParams =
| AddParams
| LogParams;
type Call = {
(...args: AddParams): Promise<number>;
(...args: LogParams): Promise<void>;
};
Затем, например:
const call: Call = (...args: ActionParams): Promise<any> => {
// (Dummy implementation)
if (args[0] === 'add') {
return Promise.resolve(args[1] + args[2]);
}
return Promise.resolve();
};
На детской площадке
С просто перегруженной функцией
Если вы просто хотите написать перегруженную функцию, вам не нужен тип Call
(вы, вероятно, знаете это):
type AddAction = ['add', number, number];
type LogAction = ['log', string];
type Actions =
| AddAction
| LogAction;
function call(...args: AddAction): Promise<number>;
function call(...args: LogAction): Promise<void>;
function call(...args: Actions): Promise<any> {
// ...implementation...
}
call('add', 1, 2)
.then(value => {
// Here, TypeScript infers `value` is of type `number`
});
call('log', 'message')
.then(value => {
// Here, TypeScript infers `avlue` is of type `void`
});
На игровой площадке