TypeScript版本: 3.4.5
搜索词:
反应默认道具defaultProps功能组件无状态
码
import React from "react";
interface Props {
name: string;
optional: string;
}
const Component = ({ name, optional = "default" }: Props) => (
<p>{name + " " + optional}</p>
);
const Test = () => <Component name="test" />;
预期行为:
按照打字稿3.0发行说明中, optional
道具不应该需要Test
,因为它已经有一个默认情况下使用ES2015默认初始化的功能被定义Component
。
实际行为:
引发以下编译错误:
类型'{name:string;类型中缺少属性'optional'。 }”,但在“道具”类型中为必填项。
游乐场链接:
链接
看起来游乐场不支持TSX。
相关问题:
文档可能不清楚,但是您必须在Props
接口中将该属性标记为可选:
interface Props {
name: string;
optional?: string;
}
这似乎与发行说明所说的不符:
export interface Props {
name: string;
}
// ...
function Greet({ name = "world" }: Props) {
return <div>Hello {name.toUpperCase()}!</div>;
}
将prop设置为可选还意味着,当您在组件外部(在测试中)访问props时,类型系统不保证prop存在,即使它始终存在。
例:
const wrapper = shallow(<Test/>);
// optional is string | undefined instead of string
const optional = wrapper
.find(Component)
.props()
.optional;
如果optional
是一个函数,则必须在执行前检查它是否存在。 例如,如果您提供一个默认的onClick
道具,它仅调用preventDefault
。
使用TypeScript 3.1或更高版本,您应该能够编写:
export interface Props {
name: string;
}
function Greet(props: Props) {
return <div>Hello {props.name.toUpperCase()}!</div>;
}
Greet.defaultProps = {
name: "world",
} as Partial<Props>; // Good practice, without it you could use a number as default prop and TypeScript wouldn't complain…
const component = <Greet />; // no errors
使用默认初始化器功能不适用于默认道具是否是一个错误? 鉴于发行说明中提供的示例不适用于最新的TypeScript版本,这似乎是一种回归。
@tbassetto的问题是TS不会强迫您实际提供默认值:
import React from 'react';
interface Props {
myProp: string;
}
const Comp = (props: Props) => {
return (
<div>
{props.myProp.toUpperCase()}
</div>
);
};
Comp.defaultProps = {
} as Pick<Props, 'myProp'>;
const comp = <Comp />;
另一个烦人的事情是您必须首先执行以下操作:如果我键入Comp
作为React.FC<Props>
,则可以很好地键入defaultProps
,但是会出现其他问题。
总而言之,TypeScripts JSX / React支持现在似乎处于一种奇怪的“不完美”状态,但是运行起来似乎一切都很好(至少在我看来-主要是,我似乎找不到任何可靠的注释了目前在3.4.5中以一种类型安全的方式来执行无状态React组件的“官方”方式)。
尽管我看到每个人都引用了变通方法,但是我无法让他们中的任何一个工作。
我正在使用3.3.3版本
export interface Props {
shouldTruncateContent: boolean;
}
const Alert: React.FunctionComponent<Props> = ({
children,
shouldTruncateContent = false
}) => {
return (
<S.Content shouldTruncateContent={shouldTruncateContent} size="fill">
{children}
</S.Content>
);
};
Alert.defaultProps = {
shouldTruncateContent: false
} as Pick<Props, 'shouldTruncateContent'>;
export default Alert;
有谁对为什么这仍然引发错误有任何见解
TS2741: Property 'shouldTruncateContent' is missing in type '{ children: string; }' but required in type 'Props'.
我也尝试了#27425和#519中提出的所有修补程序。
尽管我看到每个人都引用了变通方法,但是我无法让他们中的任何一个工作。
我正在使用3.3.3版本
export interface Props { shouldTruncateContent: boolean; } const Alert: React.FunctionComponent<Props> = ({ children, shouldTruncateContent = false }) => { return ( <S.Content shouldTruncateContent={shouldTruncateContent} size="fill"> {children} </S.Content> ); }; Alert.defaultProps = { shouldTruncateContent: false } as Pick<Props, 'shouldTruncateContent'>; export default Alert;
有谁对为什么这仍然引发错误有任何见解
TS2741: Property 'shouldTruncateContent' is missing in type '{ children: string; }' but required in type 'Props'.
我也尝试了#27425和#519中提出的所有修补程序。
您只需要使shouldTruncateContent:boolean; 可选的shouldTruncateContent?: boolean;
文档可能不清楚,但是您必须在
Props
接口中将该属性标记为可选:interface Props { name: string; optional?: string; }
我在各处都使用此可选类型。 为什么要投反对票? 有人可以解释吗?
@ralexhassle ,我无法解释反对票,但我可以解释那肯定是键入组件的optional属性的正确方法。
您可能更喜欢使用defaultProps
,这个问题的示例未使用它,但是就我而言,将可选属性标记为optional可能非常好...
问题的目的是道具不是可选的,而是具有默认值的(因此在使用组件时可以省略)。 如果使用?
将prop标记为可选,则TS会认为它可能是未定义的,并迫使您处理这种情况。 但是,由于存在默认值,因此永远不会被不确定。 降低投票率是因为评论员似乎不了解该问题,并提出了与3.0版本说明矛盾的内容。
@RyanCavanaugh僵尸
也许我错过了,但是尽管有很多解决方法,但我看不到实际的答案?
PS:使用TypeScript v4
您可以通过这种方式进行操作,此处“道具”中的属性是可选参数,并在组件中进一步使用。
interface Props {
children: ReactNode;
properties?: Record<string, unknown>;
}
const defaultProps: Props = {
children: '',
properties: {
marginTop: 32,
marginLeft: 0,
marginBottom: 8,
marginRight: 0,
},
};
const RadioListLabel: React.FC<Props> = ({
children,
properties = defaultProps.properties,
}) => (
<View
margin={[
properties ? properties.marginTop : 0
properties ? properties.marginLeft : 0
properties ? properties.marginBottom : 0
properties ? properties.marginRight : 0
]}
>
<Text size="m" variant="heading2" lineHeight="body">
{children}
</Text>
</View>
)
@lakhmeranikita此问题的目的是避免将prop类型标记为可选。
我无法获取函数默认参数或其他建议以正确进行类型检查。 我能够找到的唯一可行的解决方案是:
import React from "react";
type DefaultProps = { optionalProp: number };
type Props = {
requiredProp: "some_string" | "other_string";
} & DefaultProps;
export const BaseComponent = (props: Props) => {
const { requiredProp, optionalProp } = props;
return (
<div>
{requiredProp} {optionalProp}
</div>
);
};
BaseComponent.defaultProps = {
optionalProp: 0,
} as Partial<DefaultProps>;
const comp = <BaseComponent requiredProp="some_string" />;
最有用的评论
使用TypeScript 3.1或更高版本,您应该能够编写: