使用Typescript 3.5+在React中覆盖儿童道具

Vla*_*hek 7 typescript reactjs

我有一种情况,我想显式地将React.FC的子组件的作用域限定为特定类型,并覆盖默认的React.ReactNode

目的是要创建一个小的库,并且要产生编译时错误,该错误将告诉用户他只能将特定的组件类型用作父级的子级。

一个好的例子是:

<MainComponent>
    <ChildComponent>
</MainComponent>
Run Code Online (Sandbox Code Playgroud)

一个失败的例子是:

<MainComponent>
    <Route ...>
    <ChildComponent>
</MainComponent>
Run Code Online (Sandbox Code Playgroud)
  • 这应该失败,因为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 };
Run Code Online (Sandbox Code Playgroud)

我尝试过的是这样的:

Omit<React.FC, 'children'> & {
  children: ChildComponent | ChildComponent[];
}
Run Code Online (Sandbox Code Playgroud)

但是我只能得到React.ReactNode我的孩子和我的工会React.ReactNode

我似乎无法弄清楚如何覆盖此道具,以便仅将我的类型明确用于此道具。

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

DaG*_*ner 5

不行,这是不可能的。

<MainComponent>
    <ChildComponent/>
</MainComponent>
Run Code Online (Sandbox Code Playgroud)

是JSX语法,将被编译为

<MainComponent>
    <ChildComponent/>
</MainComponent>
Run Code Online (Sandbox Code Playgroud)

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

JSX结果类型

默认情况下,JSX表达式的结果键入为any。您可以通过指定JSX.Element接口来自定义类型。但是,无法从此接口检索有关JSX的元素,属性或子级的类型信息。这是一个黑匣子。

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

当前对此存在一个未解决的问题,其中路线图如何JSX.Element可以得到概括以支持您的用例,但没有任何明确的时间表来确定何时何地,何时落地。