TypeScript:如何根据第一个参数的值使第二个可选参数成为必需

时间:2019-03-14 23:19:57

标签: typescript typescript-typings

说我有一个需要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

任何帮助将不胜感激!

2 个答案:

答案 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

相关问题