通用和映射类型缩小

Generic & Mapped Type Narrowing

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;
  }
}

此代码生成

TypeError on props.modalProps (LoginFormProps is not assignable to SignupFormProps).

ModalTypeswitch 语句中缩小为 'login' 时,我希望 modalProps 被键入为 ModalProps['switch'] (SignupFormProps) 但它仍然输入为 ModalProps[K].

我做错了什么?

像这样的类型守卫通常与有区别的联合一起工作。您可以使用 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;
    }
}

不确定为什么您的原始代码不起作用,类型保护通常对缩小类型非常挑剔。