通用&映射类型缩小

时间:2018-05-18 11:20:44

标签: typescript typescript2.0

type ModalProps = {
  login: LoginModalProps;
  signup: SignupModalProps;
};

interface ModalRootProps<K extends keyof ModalProps> {
  modalType: K;
  modalProps: ModalProps[K];
}

export function ModalRoot<ModalType extends keyof ModalProps>(props: ModalRootProps<ModalType>) {
  switch (props.modalType) {
    case 'login': {
      return <LoginModal {...props.modalProps}/>;
    }

    case 'signup': {
      return <SignupModal {...props.modalProps} />;
    }

    default:
      return null;
  }
}

此代码会产生

  

props.modalProps上的TypeError(LoginFormProps不能分配给   SignupFormProps)。

ModalType语句中将'login'缩小到switch时,我希望modalProps可以输入为ModalProps['switch'](SignupFormProps),但它仍然是输入为ModalProps[K]

我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

这样的类型警卫通常适用于有区别的工会。您可以使用ModalProps创建这样的类型,然后类型保护将按预期工作。

type ModalRootProps<T extends keyof ModalProps> =  T extends keyof ModalProps ? { modalProps: ModalProps[T], modalType: T}: never 

export function ModalRoot(props: ModalRootProps<keyof ModalProps>) {
    switch (props.modalType) {
        case 'login': {
            return <LoginModal { ...props.modalProps } />;
        }
        case 'signup': {
            return <SignupModal { ...props.modalProps } />;
        }

        default:
            return null;
    }
}

不确定为什么原始代码不起作用,类型保护通常非常特别关于缩小类型。