javascript - Hvordan utlede returtypen til Promise basert på funksjonsargumenter?
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
})
Hvordan baserer du returverdien til Promise på hvilke som helst argumenter som ble sendt til funksjonen?
Svar #1
To tilnærminger for deg:
- Med din
Call-type som en overbelastet funksjonstype - Med bare en overbelastet funksjon.
Med din Call-type
Typen du vil ha for Call er en overbelastet funksjonstype. Du kan definere den slik:
type Call = {
(...args: ['add', number, number]): Promise<number>;
(...args: ['log', string]): Promise<void>;
};
Siden du trenger å knytte en returtype til parameterlisten, hjelper ikke Actions-typen egentlig.
En funksjon skrevet med den typen vil gjøre inferensen du har bedt om:
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`
});
}
På lekeplassen
Hvis du skal skrive funksjoner for det, kan det være nyttig å ha noen hjelpetyper:
type AddParams = ['add', number, number];
type LogParams = ['log', string];
type ActionParams =
| AddParams
| LogParams;
type Call = {
(...args: AddParams): Promise<number>;
(...args: LogParams): Promise<void>;
};
Så for eksempel:
const call: Call = (...args: ActionParams): Promise<any> => {
// (Dummy implementation)
if (args[0] === 'add') {
return Promise.resolve(args[1] + args[2]);
}
return Promise.resolve();
};
På lekeplassen
Med bare en overbelastet funksjon
Hvis du bare vil skrive en overbelastet funksjon, trenger du ikke Call-typen (det vet du sikkert):
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`
});
På lekeplassen
