当我想设置特定props时,TypeScript 和 JSX 不理解情况

IT技术 reactjs typescript jsx
2021-05-21 09:54:35

我想在组件中设置特定的 props 并且我有这个类型,但是当我尝试使用 JSX 设置错误的 props 时,编译器没有向我显示错误。仅当我使用 React.createElement 时才会收到错误,但我没有看到使用 JSX 的 TypeError。

例如,对于组件的两个 props,我们有两种类型

type T1 = {
    a: boolean
}

type T2 = {
    b: string;
    c: number;
}

我们有两个具有特定props的组件

var MyComponenWithT1: React.FC<T1> = ({ a }) => <div>{a ? 1: 2}</div>;
var MyComponenWithT2: React.FC<T2> = ({ b }) => <div>{b ? 1: 2}</div>;

我尝试定义两个元素

var GoodElement: React.ReactElement<T1> = React.createElement(MyComponenWithT1, { a: true })
var WrongElement: React.ReactElement<T1> = React.createElement(MyComponenWithT2, {b: 'f', c: 5})

它运作良好。当我们尝试定义 WrongElement 时,我们看到编译器给了我们一个错误。

在这个例子中我们使用没有 React.createElement 的 JSX 并且编译器没有看到任何错误

var GoodJSXElement: React.ReactElement<T1> = <MyComponenWithT1 a={true} />
var WrongJSXElement: React.ReactElement<T1> = <MyComponenWithT2 b='f' c={5} />

现在,编译器告诉我们一切都是正确的,但实际上是错误的。MyComponenWithT2 具有类型为 T2 的props,并且不能将其分配给等待具有 T1 props的元素的变量。实际上,我们有两种相同的情况,一种情况使用 CreateElement 方法,另一种情况使用 JSX。但是我们有一个错误,另一个没有。为什么?如果我尝试将具有不正确props的元素分配给变量,我怎么能说编译器向我显示错误

TS游乐场

1个回答

的typescript定义React.FC是它返回 a 的函数,ReactElement其中 props 和 type 的泛型都是any(或返回null)。一旦函数被调用以生成一些 HTML 代码,返回的代码就不会知道用于创建它的 props。

type FC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
    (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
    propTypes?: WeakValidationMap<P>;
    contextTypes?: ValidationMap<any>;
    defaultProps?: Partial<P>;
    displayName?: string;
}

当您使用 JSX 时,您基本上只是调用该函数。如果您从变量删除类型,你会看到,无论是GoodJSXElementWrongJSXElement有型JSX.Element

React.createElement有不同的返回类型。这是重载之一:

function createElement<P extends {}>(
    type: FunctionComponent<P> | ComponentClass<P> | string,
    props?: Attributes & P | null,
    ...children: ReactNode[]): ReactElement<P>;

您会注意到它返回ReactElement<P>而不是ReactElement<any>直接调用函数组件时返回的。所以这就是有区别的原因。

元素基本上是解析后的 H​​TML。如果它不关心它是如何创建的,我质疑为什么关心。我怀疑你的设计在其中,代替绕过的方式进行改写ReactElement,你绕过ComponentType来代替。