【问题标题】:Overriding children prop in React with Typescript 3.5+使用 Typescript 3.5+ 在 React 中覆盖 children 道具
【发布时间】:2019-08-22 23:29:04
【问题描述】:

我有一个案例,我想明确地将 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 或我的孩子和React.ReactNode 的联合。

我似乎无法弄清楚如何覆盖该道具以仅显式地将我的类型用于该道具。

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

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    不,这是不可能的。

    <MainComponent>
        <ChildComponent/>
    </MainComponent>
    

    是 JSX 语法,将被编译为

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

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

    The JSX result type

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

    您可以将children 覆盖为仅stringfunction(以实现类似渲染道具模式),但任何自定义组件都将被强制转换为JSX.Element,这是文档中所述的黑盒.

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

    【讨论】:

    • 嗨达加德纳。看到这种情况我很难过。不过,我感谢您的回答。
    猜你喜欢
    • 2017-11-27
    • 2019-01-11
    • 2019-10-23
    • 1970-01-01
    • 2021-04-01
    • 2022-01-24
    • 1970-01-01
    • 2022-01-15
    • 2021-01-24
    相关资源
    最近更新 更多