reactjs - 使用 Typescript 3.5+ 在 React 中覆盖子属性

标签 reactjs typescript

我有一个案例,我想明确地将 React.FC 的子组件限定为特定类型,覆盖默认值:React.ReactNode.

目的是我正在创建一个小库,并且我希望出现编译时错误,告诉用户他只能将特定组件类型用作父组件的子组件。

一个OK的例子是:

<MainComponent>
    <ChildComponent>
</MainComponent>

一个失败的例子是:

<MainComponent>
    <Route ...>
    <ChildComponent>
</MainComponent>
  • 这应该会失败,因为 Route 组件不是 ChildComponent 并且无法通过检查。

React.FC 中的默认子属性派生自:

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

type PropsWithChildren<P> = P & { children?: ReactNode };

我试过的是这样的:

Omit<React.FC, 'children'> & {
  children: ChildComponent | ChildComponent[];
}

但是我可以只获得 React.ReactNode 或我的 child 和 React.ReactNode 的联合。

我似乎无法弄清楚如何覆盖 prop 以仅明确将我的类型用于该 prop。

我正在使用 Typescript 3.5.3 和 Omit/Extend ... 现在已成为标准 TS 库的一部分。

最佳答案

不,这是不可能的。

<MainComponent>
    <ChildComponent/>
</MainComponent>

是 JSX 语法,将被编译为

React.createElement(MainComponent, null, React.createElement(ChildComponent, null));

然后我们必须看看 typescript 如何处理这些 JSX 元素。这在他们的手册中有明确记录:

The JSX result type

By default the result of a JSX expression is typed as any. You can customize the type by specifying the JSX.Element interface. However, it is not possible to retrieve type information about the element, attributes or children of the JSX from this interface. It is a black box.

您可以将 children 重写为 stringfunction(以实现类似 render prop 模式的东西),但任何自定义组件都将获得转换为 JSX.Element,这是文档中所述的黑盒。

目前有一个 issue为此开放,其中有一个路线图,说明如何将 JSX.Element 泛化以支持您的用例,但没有明确的时间表,何时、在何种程度上或是否会落地。

关于reactjs - 使用 Typescript 3.5+ 在 React 中覆盖子属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57119381/

相关文章:

html - react 中的 <details> 是什么?

css - 为什么 ThemeProvider(Material UI)在这里不适合我?

typescript - 如何使用 ts 将 ref 数据定义为 vue3 中的类类型

javascript - 高阶 React 组件中可选参数的流类型

javascript - webpack babel loader 编译 jsx 失败

javascript - Express.js 或 React.js 中的通用用户名/密码身份验证

reactjs - 如何使用 Typescript 将组件传递到 react 路由器路由中?

css - 向 TypeScript、React NPM 包添加样式

javascript - 替换字符串中的某个字符javascript

Angular 2 和浏览器自动填充