不幸的是,使用the void
type来生成function parameter optional(如在microsoft/TypeScript#27522中实现的)并不完全受支持.它不像microsoft/TypeScript#29131中描述的那样,倾向于与generics一起工作.这被认为是TypeScrip中的一个错误,但它已经存在了很长一段时间,没有迹象表明它会很快或永远得到修复.出于这个原因,我建议您避免使用void
(事实上,void
在很多情况下都表现得很奇怪,所以您可能应该总是稍作停顿,以确保它确实是您想要使用的).
相反,您可以使用rest parameter of a tuple type实现"可能可选"的函数参数,其中元组类型取决于您要判断的任何条件.例如:
const openModal = <T,>(
modal: (props: T) => void,
...[props]: {} extends Omit<T, "onClose"> ?
[props?: Omit<T, "onClose">] :
[props: Omit<T, "onClose">]
) => {
return;
};
因此,从技术上讲,openModal
是一个变量函数,其剩余参数...[props]
是类型[props?: Omit<T, "onClose">]
(元素为optional的单元素元组)或类型[props: Omit<T, "onClose">]
(元素是必需的单元素元组).因为...[props]
使用destructuring assignment,所以这会在函数内部给出一个props
参数,它的类型是Omit<T, "onClose">
还是Omit<T, "onClose"> | undefined
,具体取决于类型T
.
当你调用它时,如果空对象类型可以赋值给T
,那么你可以用一个参数调用openModal()
.否则需要两个参数:
const ModalOne = (props: { onClose: () => void }) => { };
openModal(ModalOne); // okay
openModal(ModalOne, {});// okay
openModal(ModalOne, undefined); // okay
const ModalTwo = (props: { text: string, onClose: () => void }) => { };
openModal(ModalTwo); // error
openModal(ModalTwo, {}); // error
openModal(ModalTwo, undefined); // error
openModal(ModalTwo, { text: 'test' }); // okay
const ModalThree = (props: { text?: string, onClose: () => void }) => { };
openModal(ModalThree); // okay
openModal(ModalThree, {}); // okay
openModal(ModalThree, undefined); // okay
openModal(ModalThree, { text: 'test' }); // okay
看起来像你想要的行为.
Playground link to code