javascript - Skicka in parametrar till funktion genom att sprida ett parametrar-objekt fungerar inte
Jag vill skicka in alla parametrar till den här funktionen genom att sprida ett params-objekt på det här sättet, som detta SO-svar:
public showToast(
content: string,
buttonLabel = 'Ok',
hideDelay?: number,
buttonAction?: Function,
uniqueKey?: string,
canBeCleared?: boolean,
templateCtrl?: Object
): Toast {
const toast = new Toast(
content,
this,
buttonLabel,
hideDelay,
buttonAction,
uniqueKey,
canBeCleared,
templateCtrl
);
toast.id = !this.lastToast ? 1 : this.lastToast.id + 1;
this.toasts.push(toast);
toast.top = toast.fromTop;
// hiding is handled in the ToastComponent
return toast;
}
Mitt försök:
const toastArgs = {
content: 'test toast',
buttonLabel: 'test button',
hideDelay: 1000,
buttonAction: () => 5,
uniqueKey: 'uk',
canBeCleared: true,
templateCtrl: { strl: 3 }
};
service.showToast(...Object.values(toastArgs));
Komplileringstidens fel:
Förväntade 1-7 argument, men fick 0 eller fler.ts(2556) toast.service.ts(18, 9): Ett argument för 'content' gavs inte.
Varför får jag detta fel? Jag har följt SO-svaret.
Svar #1
Du får detta eftersom Object.values(toastArgs) tolkas som:
(true | "test toast" | "test button" | 1000 | (() => number) | "uk" | {
readonly strl: 3;
})[]
Typescript har egentligen inte begreppet av en arrays 'length'. Såvitt typescript är bekymrad, skulle toastArgs kunna vara { x: true }, och det skulle uppfylla typen av Object.values(toastArgs). Du kan testa detta så här:
const toastArgsValid = {
content: 'test toast',
buttonLabel: 'test button',
hideDelay: 1000,
buttonAction: () => 5,
uniqueKey: 'uk',
canBeCleared: true,
templateCtrl: {strl: 3},
};
const toastArgsValuesValid = Object.values(toastArgsValid);
type ToastParamsValid = typeof toastArgsValuesValid;
const toastArgsInvalid = {
x: true,
};
const toastArgsValuesInvalid: ToastParamsValid = Object.values(
toastArgsInvalid,
); // No error here since the invalid type is a subtype of the valid type
Ett sätt att uppnå det du letar efter är att refaktorera din showToast-metod för att istället ta ett enda objekt, istället för positionsargument:
public showToast({
content,
buttonLabel,
hideDelay,
buttonAction,
uniqueKey,
canBeCleared,
templateCtrl,
}: {
content: string;
buttonLabel: string;
hideDelay?: number;
buttonAction?: Function;
uniqueKey?: string;
canBeCleared?: boolean;
templateCtrl?: Object;
}): Toast {
// function body
}
Du kan då kalla:
service.showToast(toastArgs)
Alternativt kan du också använda en typförklaring, utan att refaktorera din kod på följande sätt:
service.showToast(...(Object.values(toastArgs) as Parameters<typeof service.showToast>));
Svar #2
Object.values() stöds från es2017, ECMAScript_2017. Och standardmålversionen för TypeScript är ES3. Felet kan åtgärdas genom att helt enkelt lägga till kompilatoralternativet --target es2017.
