首页 > 解决方案 > TypeScript 类型,它排除了泛型参数为 `any` 的类型

问题描述

这是 React FunctionComponent 的 TypeScript 类型的一个分支,它只返回一个 IntrinsicElement

React 定义

declare namespace JSX {
  type Element = React.ReactElement<any, any>;
}

虽然我在 中找不到它@types/react/index.d.ts,但渲染 a会<Fragment>返回 a JSX.Element。所以,如果我想为一个函数定义一个类型,该函数只返回一个 HTML 元素(即不是 a Fragment,除非它只有一个子元素,这会破坏它的目的),我需要以某种方式将我的返回类型限制为类似

type IntrinsicFC = 
  () => Exclude<JSX.IntrinsicElements[keyof JSX.IntrinsicElements], ReactElement<any, any>>;

(注意:Exclude<..., ReactElement<any, any>>并不意味着我所期望的;它似乎与JSX.IntrinsicElements[keyof JSX.IntrinsicElements]虽然我不明白为什么相同。但是,为了这个问题,假设我确实知道我试图表达的正确类型。)

然而,any强类型的消亡,因为每个 HTML 元素都扩展ReactElement<any, any>,这将使我的类型() => never

有没有办法排除类型别名的类型SomeGenericType<any>

我最近一次失败的尝试IntrinsicFC是:

type IntrinsicElement = JSX.IntrinsicElements[keyof JSX.IntrinsicElements];

type IntrinsicFC<P = void> =
  ((props: P) => IntrinsicElement) extends ((props: P) => JSX.IntrinsicElements[infer U & keyof JSX.IntrinsicElements])
    ? U extends keyof JSX.IntrinsicElements
      ? ((props: P) => JSX.IntrinsicElements[U])
      : never
    : never;

然而,这会导致type IntrinsicFC<P = {}> = never;,因为IntrinsicElement 总是扩展,因为JSX.IntrinsicElements[keyof JSX.IntrinsicElements]它是相同的定义。

TS游乐场


我怀疑当 React 团队编写声明文件时,它们的意思JSX.Element是定义为

type Element = React.ReactElement<unknown>;

但是该类型早于 TypeScript v3.0.0,它引入了unknowntype,现在更改它将是一个重大更改。但是,我只是尝试手动更改类型声明,还是不行,所以... ‍♀️</p>

标签: typescript

解决方案


推荐阅读