这是注册组件:
import { type IResolveParams } from 'reactjs-social-login';
import { Box, Divider } from '@chakra-ui/react';
import { EmailSignupForm, type EmailSignupDataSchema } from './EmailSignupForm';
import { SocialSignups } from './SocialSignups';
import { SignupLoading } from './SignupLoading';
type SignupProvider = 'email' | 'facebook' | 'google' | 'linkedin';
type SignupData<T extends SignupProvider> = T extends 'email'
? {
provider: 'email';
data: EmailSignupDataSchema;
}
: IResolveParams;
type BackendError<T extends SignupProvider> = T extends 'email'
? {
provider: 'email';
errors: Partial<EmailSignupDataSchema>;
}
: {
provider: Omit<SignupProvider, 'email'>;
error: string;
};
type SignupProps = {
onSubmit: (data: SignupData<SignupProvider>) => void;
isLoading?: boolean;
backendError?: BackendError<SignupProvider>;
};
export const Signup = ({
onSubmit,
isLoading,
backendError,
}: SignupProps): JSX.Element => {
const onEmailSignupFormSubmit = (data: EmailSignupDataSchema): void => {
onSubmit({
provider: 'email',
data,
});
};
return (
<Box
minW={{ base: '90%', md: '468px' }}
backgroundColor="whiteAlpha.900"
boxShadow="md"
px={5}
py={8}
position="relative"
>
{isLoading === true ? <SignupLoading /> : null}
<EmailSignupForm
onSubmit={onEmailSignupFormSubmit}
backendError={
backendError?.provider === 'email' ? backendError.errors : undefined
}
/>
<Divider />
<SocialSignups
onSubmit={onSubmit}
backendError={
backendError?.error != null ? backendError.error : undefined
}
/>
</Box>
);
};
并抱怨说:
Property 'errors' does not exist on type '{ provider: "email"; errors: Partial<{ email: string; password: string; confirmPassword: string; captchaToken: string; }>; } | { provider: Omit<SignupProvider, "email">; error: string; }'.
Property 'errors' does not exist on type '{ provider: Omit<SignupProvider, "email">; error: string; }'.
对于属性“错误”,也是一样的。
怎么回事?打印得很清楚。我漏了什么?
我的理解是,如果BackendError有一个提供程序'email',它将具有errors
属性,如果提供程序是其他的,那么它将具有error
属性。
1条答案
按热度按时间mzsu5hc01#
问题是
backendError
结构化参数的类型BackendError
是一个联合类型。因此,Typescript无法确定它是包含error
属性的类型还是包含errors
属性的类型。但是 * 你 * 在使用
errors
之前检查provider === 'email'
是否存在,而且你 * 在使用backendError?.error
之前检查它是否存在!这应该足以确定backendError
的精确类型,对吗?好吧,是的,从我的Angular 来看。显然不是从TS的Angular 来看。显然,对于第一种情况,TS被
provider
可以接受包含errors: Partial<EmailSignupDataSchema>
的类型的值'email'
的事实所迷惑,或者包含error: string
的类型的几个其他值之一。如果provider
的每个可能值都有一个类型,这是可行的-就像文档中的歧视工会的例子一样。然而,我不知道为什么TS不理解你的方式。对于第二种情况,使用
?.
测试属性的存在性显然会导致这个错误,因为使用这个操作符需要指定属性的存在性。因此,将代码更改为以下内容应该可以工作:你可以对
errors
做同样的事情,并完成它:或者使用类型 predicate 函数:
并且: