如何根据函数参数推断Promise的返回类型


type Actions =
| ['add', number, number] // should return number
| ['log', string]; // should return void

type Call = (...args: Actions) => Promise<?>;
const call: Call = (...args: Actions): Promise<?> => {
// returns some Promise
}
call('add', 1, 1).then(value => {
// value is then inferred as number
})

call('log', 'Hello World!').then(value => {
// value is then inferred as void
})

如何根据传递给函数的任何参数来确定Promise的返回值?

有两种方法:

  1. Call类型作为重载函数类型
  2. 只有一个重载函数

使用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`
});

在操场上

最新更新