在全局JSX命名空间被弃用后,JSX.Element的正确返回类型替代是什么?

huangapple go评论70阅读模式
英文:

What is the correct return type replacement for JSX.Element after the global JSX namespace has been deprecated?

问题

@types/react中,全局JSX命名空间已被弃用

declare global {
    /**
     * @deprecated Use `React.JSX` instead of the global `JSX` namespace.
     */
    namespace JSX {
    ...
    }
}
英文:

In @types/react, the global JSX namespace has been deprecated:

declare global {
    /**
     * @deprecated Use `React.JSX` instead of the global `JSX` namespace.
     */
    namespace JSX {
    ...
    }
}

Since I have ESLint's deprecation/deprecation rule (from plugin eslint-plugin-deprecation) enabled, I now receive errors for return types of function components like this:

export default function TestComponent(): JSX.Element { // This JSX is marked as deprecated
    return (
        <span>Test</span>
    );
}

What is the correct return type replacement for JSX.Element in this case now that the global JSX namespace is deprecated?

Is it React.JSX.Element as stated in the deprecation message like this:

export default function TestComponent(): React.JSX.Element { ... }

Or is it ReactElement like this:

import { ReactElement } from "react";
export default function TestComponent(): ReactElement { ... }

Or is it best to declare the function component using React.FC and let TypeScript infer the return type like this:

export const TestComponent: React.FC = () => { ... };

答案1

得分: 20

Use directly React.ReactElement (or, to be more precise, React.ReactElement | null):

import { ReactElement } from "react";

export function TestComponent(): ReactElement | null {
  return (
    Math.random() < 0.5
      ? null
      : <>
          A single Element (could be a Fragment like here)
        </>
  );
}

This is exactly what (the no longer recommended) React.FC enforces:

interface FunctionComponent<P = {}> {
  (props: P, context?: any): ReactElement<any, any> | null;
  // ...
}

And it is also the definition of a JSXElementConstructor:

type JSXElementConstructor<P> =
  | ((props: P) => ReactElement<any, any> | null) // Case of a Function Component
  | (new (props: P) => Component<any, any>); // Case of a Class-based Component

That being said, unless you have some rule forcing you to type your Function Component return type, you can just omit it for easiness:

export function TestComponent() {
  // ...
}

Obviously, that function can now return anything, and TypeScript will not complain... except when you try using it as a Function Component in a JSX template, as pointed out in fb/cra#8177:

The only benefit I really see to React.FC [...] is that it specifies the return type, which catches mistakes [...]

In practice, I think this is fine, as it'll be caught as soon as you try to use it:

const Example = () => <Component />; // Error here, due to Component returning the wrong thing
英文:

Use directly React.ReactElement (or, to be more precise, React.ReactElement | null):

import { ReactElement } from &quot;react&quot;;

export function TestComponent(): ReactElement | null {
  return (
    Math.random() &lt; 0.5
      ? null
      : &lt;&gt;
          A single Element (could be a Fragment like here)
        &lt;/&gt;
  );
}

This is exactly what (the no longer recommended) React.FC enforces:

interface FunctionComponent&lt;P = {}&gt; {
  (props: P, context?: any): ReactElement&lt;any, any&gt; | null;
  // ...
}

And it is also the definition of a JSXElementConstructor:

type JSXElementConstructor&lt;P&gt; =
  | ((props: P) =&gt; ReactElement&lt;any, any&gt; | null) // Case of a Function Component
  | (new (props: P) =&gt; Component&lt;any, any&gt;); // Case of a Class-based Component

That being said, unless you have some rule forcing you to type your Function Component return type, you can just omit it for easiness:

export function TestComponent() {
  // ...
}

Obviously, that function can now return anything, and TypeScript will not complain... except when you try using it as a Function Component in a JSX template, as pointed out in fb/cra#8177:
> The only benefit I really see to React.FC [...] is that it specifies the return type, which catches mistakes [...]
>
> In practice, I think this is fine, as it'll be caught as soon as you try to use it:

const Example = () =&gt; &lt;Component /&gt;; // Error here, due to Component returning the wrong thing

答案2

得分: 7

Use React.JSX.
或者从 “react” 导入 JSX

import {JSX} from 'react'
英文:

Use React.JSX.


Or import JSX from &quot;react&quot;:

import {JSX} from &#39;react&#39;

huangapple
  • 本文由 发表于 2023年5月11日 14:53:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76224848.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定