reactjs - 当一个带有错误 props 的 React 函数组件(React.FC)作为 prop 传递时,TypeScript 为什么不报错?
我正在尝试将一个带有一些 props 的函数组件发送到另一个组件,并在接收组件中尝试对该组件的一些 props 进行类型检查。以下是代码:
// BaseButton.tsx
export type ButtonProps = {
label: string
size?: 'sm' | 'md' | 'lg' | 'normal'
icon?: React.FC<{ size?: number; foo: string }>
} & React.ButtonHTMLAttributes<HTMLButtonElement
export const BaseButton: React.FC<ButtonProps> = props => {/* ...return the button component */}
// Icon.tsx
type Props = {
style?: React.CSSProperties
size?: number
}
export const Icon: React.FC<Props> = ({ style, size = 24 }) => {/* ... return Icon component */}
// where I render the component
<BaseButton icon={Icon} label="Sign in" />
// ^^^ I am expecting Typescript to complain
由于 ButtonProps 中的 icon?: React.FC<{ size?: number; foo: string }> 有一个额外的属性 foo,我本以为 TypeScript 会对此发出警告。但事实并非如此。
编辑:
在尝试用 JSX 语法调用它时,这将抛出一个错误:
icon?: React.FC<{ size?: number; foo: string }>
const {icon: Icon} = props
<Icon />
相反,类型应该是:
icon?: React.ComponentType<{ bar: number }>答案#1
基本上,你可以将参数较少的函数分配给参数较多的函数:
let fn1 = (props: { size: number }) => 42
let fn2 = (props: { size: number; foo: string }) => 42
fn2 = fn1 // this works
fn1 = fn2 // error
或者换句话说:
对于一个变量 let fn2,其类型为 (props: { size: number; foo: string }) => number,客户端需要使用两个属性 size 和 foo 来调用它。现在我们可以将 fn2=fn1,因为底层实现 fn1 可以忽略某些输入属性,只处理 size。
转到您的案件:
具有类型 React.FC<{ style?: React.CSSProperties; size?: number}> 的 Icon 可以赋值给具有类型 React.FC<{ size?: number; foo: string }> 的 ButtonProps 的 icon 属性。
let fc1: React.FC<{
style?: React.CSSProperties
size?: number
}> = // ...
let fc2: React.FC<{ size?: number; foo: string }> = // ...
fc2 = fc1 // works
fc1 = fc2 // error
操场
答案#2
类型 FunctionComponent 有函数类型定义,因此你可以传递一个 React 组件或一个将来要调用的函数。
type FC<P = {}> = FunctionComponent<P>;
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement | null; <--- Here
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
这是一个沙盒,展示了如何从 BaseButton 组件中调用 props.icon 组件。你将看到在第 21 行调用该函数时,必须传递 props foo 和 size。
https://codesandbox.io/s/trusting-banach-prwos?file=/src/App.tsx
https://www.typescriptlang.org/docs/handbook/interfaces.html#function-types
