说我有一个需要2个args的函数,根据第一个arg的值,可能需要也可能不需要第二个args。
例如:
function calculate(item: 'icon' | 'category', state: IState): void {
if (arg1 === 'icon') {
// code in which I don't need to access anything in state
}
if (arg1 === 'category') {
// code in which I do need to access state
}
}
如果我按原样运行它,写的时候会报错
calculate('icon') // will cause an error
这也会引发错误,因为我没有为第二个arg传递有效值
calculate('icon', null) // will also cause an error
为了不出现任何错误,我必须这样称呼
calculate('icon', this.state) // acceptable as long as 'this.state' meets the IState definition
如果第一个参数='icon',我希望能够在不传递第二个参数的情况下调用该函数。像这样
calculate('icon') // should not cause an error
但是,如果我这样调用计算,则会导致错误
calculate('category') // should cause an error
任何帮助将不胜感激!
答案 0 :(得分:8)
您可以使用多个重载:
/*Allow native mobile share of QR */
function shareQROnMobile() {if (navigator.share) {
navigator.share({
title: document.title,
text: document.title + ", " + window.location.href,
url: jQuery("#qrcode-current img")[0].src,
})
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
}}
/*END native mobile share of QR */
答案 1 :(得分:0)
这是我最终要解决的问题。如果有人知道更好的方法,请分享!
type ConditionalOptions<T, K extends keyof T> = T[K] extends null ? [] : [T[K]];
interface IPossibleValues {
icon: {
state: IState;
};
theme: null;
category: {
state: IState;
cardItem: any;
};
}
calculate = <T extends keyof IPossibleValues>(
type: T,
...options: ConditionalOptions<IPossibleValues, T>
): string => {
// code here
}
如果使用此方法,则需要将接口IPossibleValues中每个键的值作为第二个arg传递给 calculate 。例子:
calculate('icon') // this will cause an error since no 'state' is passed in
calculate('icon', { state: stateVal }) // this will not generate a type error
calculate('theme') // this will not cause any type errors
calculate('theme', someValue) // this will cause an error
calculate('category', {
state: stateVal,
cardItem: cardVal,
}) // this will not cause an error
calculate('category', { state: stateVal }) // this will cause an error because 'cardItem' was not passed in