Thi*_*ddi 10 types typescript reactjs react-proptypes
我正在将 React 应用程序从 Javascript 重构为 Typescript,但在迁移时遇到一些问题,尤其是 PropType shape。我的代码现在看起来像这样:
import React from 'react';
import PropTypes from 'prop-types';
interface FooterProps {
labels: FooterLabels;
}
interface FooterLabels {
body: string;
}
const Footer: React.FC<FooterProps> = ({ labels }) => (
<div className="footer">
{/* ... */}
</div>
);
Footer.propTypes = {
labels: PropTypes.shape({
body: PropTypes.string.isRequired
}).isRequired
};
export default Footer;
Run Code Online (Sandbox Code Playgroud)
但我在 PropTypes 中遇到错误:
Type 'Validator<InferProps<{ body: Validator<string>; }>>' is not assignable to type 'Validator<FooterLabels>'.
Type 'InferProps<{ body: Validator<string>; }>' is not assignable to type 'FooterLabels'.
Property 'body' is optional in type 'InferProps<{ body: Validator<string>; }>' but required in type 'FooterLabels'.ts(2322)
FooterAppPromo.tsx(5, 3): The expected type comes from property 'labels' which is declared here on type 'WeakValidationMap<FooterProps>'
Run Code Online (Sandbox Code Playgroud)
我是 Typescript 的新手,所以有时我真的不知道自己在做什么,但我尝试做类似的事情:
Type 'Validator<InferProps<{ body: Validator<string>; }>>' is not assignable to type 'Validator<FooterLabels>'.
Type 'InferProps<{ body: Validator<string>; }>' is not assignable to type 'FooterLabels'.
Property 'body' is optional in type 'InferProps<{ body: Validator<string>; }>' but required in type 'FooterLabels'.ts(2322)
FooterAppPromo.tsx(5, 3): The expected type comes from property 'labels' which is declared here on type 'WeakValidationMap<FooterProps>'
Run Code Online (Sandbox Code Playgroud)
但我收到了错误。我尝试搜索示例实现,但找不到任何示例。
Typescript 类型和 PropType 不是一回事。您可以轻松编写一个示例,其中 Typescript 验证通过,但您仍然收到 PropTypes 警告(例如,外部 API 返回数字,而本应是字符串)。这里有两篇文章解释了原因:
所以我的问题是如何使嵌套的 PropTypes 对象(PropTypes.shape()或者可能PropTypes.objectOf())与 TypeScript 一起使用?
PropTypes 错误是因为您尝试使用 a PropType.shape,该形状允许您在形状上具有可选值,在这种情况下,您的接口是严格的,这意味着您没有任何类型的可选值,并且React.Validator正在尝试用你的接口推断你的类型,这会导致错误出现。
简而言之,如果您有一个带有非可选值的严格接口,那么PropType.shape您应该使用PropType.exact而不是使用,这应该可以防止错误。
例如:
Footer.propTypes = {
labels: PropTypes.exact({
body: PropTypes.string
}).isRequired
};
Run Code Online (Sandbox Code Playgroud)
因此,您的错误消息会出现
属性“body”在类型“InferProps<{ body: Validator;”中是可选的 }>' 但在“FooterLabels”类型中是必需的。ts(2322)
编辑
发生这种情况只是因为您在组件上使用
const Footer: React.FC<FooterProps> = ({ labels }) => (
FC(功能组件接口)查看接口表示为
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
Run Code Online (Sandbox Code Playgroud)
这里我们应该强调的一行是propTypes?: WeakValidationMap<P>;This 行,它根据我们的 PropTypes 推断出我们的类型。
你还有第二种选择在 React 上使用类型,但我不推荐它,你可以使用ReactNode类型来代替 FC,但你将失去在 FC 接口类型推断上的推断。
例如
function Footer = ({ labels }:FooterProps): ReactNode => (
实际上你不需要propTypes这里 -labels只有一个嵌套字段body,即 typeof FooterLabels。
interface FooterProps {
labels: {
body: FooterLabels;
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8135 次 |
| 最近记录: |