使用 React.FC 在函数组件中键入默认 props 可能会导致错误类型错误:
type Props = {
required: string,
} & typeof defaultProps;
const defaultProps = {
optDefault: 'optDefault'
};
const MyComponent: React.FC<Props> = (props: Props) => (
<ul>
<li>required: {props.required}</li>
<li>optDefault: {props.optDefault}</li>
</ul>
)
MyComponent.defaultProps = defaultProps;
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent /* type error <---- false type error */
required='required'
/>
</div>,
document.getElementById('app')
);
错误:
[tsserver 2741] Property 'optDefault' is missing in type '{ required: string; }' but required in type '{ optDefault: string; }'. [E]
提出的另一种解决方案是使用Javascript自己的默认函数参数:
type Props = {
required: string,
optDefault?: string
}
const MyComponent: React.FC<Props> = ({
required,
optDefault='default'
}: Props) => (
<ul>
<li>required: {required}</li>
<li>optDefault: {optDefault}</li>
</ul>
)
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent
required='required'
/>
</div>,
document.getElementById('app')
);
但是这个解决方案的问题是,如果你忘记提供默认值,就会导致运行时错误:
const MyComponent: React.FC<Props> = ({
required,
optDefault //='optDefault' //<--- if you forgot to provide default
}: Props) => (
<ul>
<li>required: {required}</li>
<li>optDefault: {optDefault}</li> {/* <-- result in bug */}
</ul>
)
更好的解决方案是根本不使用 React.FC,只依赖 Typescript 类型推断:
type Props = {
required: string,
} & typeof defaultProps;
const defaultProps = {
optDefault: 'optDefault'
};
const MyComponent = (props: Props) => (
<ul>
<li>required: {props.required}</li>
<li>optDefault: {props.optDefault}</li>
</ul>
)
MyComponent.defaultProps = defaultProps
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent
required='required'
/>
</div>,
document.getElementById('app')
);