我想设置特定的道具时,TypeScript和JSX无法理解情况 [英] TypeScript and JSX don't understand cases when I want to set specific props

查看:51
本文介绍了我想设置特定的道具时,TypeScript和JSX无法理解情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在组件中设置特定的道具,我有相应的类型,但是当我尝试使用JSX设置错误的道具时,编译器不会显示错误.仅在使用React.createElement时出现错误,但使用JSX看不到TypeError.

I would to like to set specific props in a component and I have the types for this, but compiler doesn't show me an error when I'm trying to set wrong props using JSX. I get an error only when I use React.createElement but I don't see the TypeError using JSX.

例如,对于两种道具,我们有两种类型

For instance, We have two types for two props of components

type T1 = {
    a: boolean
}

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

我们有两个组成部分,并带有具体的道具

And We have two components with the specific 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时,我们看到编译器给了我们一个错误.

It works good. We see that compiler gives back us an error when We try to define WrongElement.

在此示例中,我们使用不带React.createElement的JSX,并且compiller没有看到任何错误

In this example We use JSX without React.createElement and compiller doesn't see any errors

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

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

Now, compiler shows us that everything is correct, but it's actually wrong. MyComponenWithT2 has props with type T2, and it can't be assigned to an variable which waits the element with T1 props. Actually, We have both equal cases one case use CreateElement method, and other use JSX. But We have the error in one and don't another. Why? And How can I say compiler to show me the error if I try to assign to the variable an element with incorrect props

TS游乐场

推荐答案

React.FC 的打字稿定义是,它是一个返回 ReactElement 的函数,其中泛型道具和类型都是 any (或者返回 null ).调用该函数以生成一些HTML代码后,返回的代码将不知道用于创建它的道具.

The typescript definition of React.FC is that it a function which returns a ReactElement where the generics for props and type are both any (or it returns null). Once the function has been called to generate some HTML code, that returned code is not aware of the props which were used to create it.

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时,您基本上只是在调用该函数.如果从变量中删除类型,则会看到 GoodJSXElement WrongJSXElement 都具有 JSX.Element 类型.

When you use JSX you are basically just calling the function. If you remove the types from your variables, you'll see that both GoodJSXElement and WrongJSXElement have the type JSX.Element.

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

React.createElement has a different return type. Here's one of the overloads:

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

您会注意到,它返回 ReactElement< P> ,而不是直接调用函数组件会得到的 ReactElement< any> .这就是为什么存在差异的原因.

You'll notice that it returns ReactElement<P> instead of the ReactElement<any> that you would get from calling the function component directly. So that's why there's a difference.

元素基本上是解析的HTML.如果它不在乎它是如何创建的,我会问为什么在乎.我怀疑您的设计可以通过以下方式重写,而不是传递 ReactElement ,而是传递 ComponentType .

An element is basically the resolved HTML. If it doesn't care how it was created, I question why you care. I suspect your design can be rewritten in a way where instead of passing around the ReactElement, you pass around the ComponentType instead.

这篇关于我想设置特定的道具时,TypeScript和JSX无法理解情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆