【问题标题】:Extending a TypeScript Type with an optional property使用可选属性扩展 TypeScript 类型
【发布时间】:2021-01-18 01:58:56
【问题描述】:

我正在使用 NextJS,需要使用我自己添加的可选参数 Layout 来扩展他们的 AppProps 类型。但是 AppProps 类型由许多其他类型组成,例如

AppProps:

export declare type AppProps<P = {}> = AppPropsType<Router, P>;

AppPropsType:

export declare type AppPropsType<R extends NextRouter = NextRouter, P = {}> = AppInitialProps & {
    Component: NextComponentType<NextPageContext, any, P>;
    router: R;
    __N_SSG?: boolean;
    __N_SSP?: boolean;
};

下一个组件类型:

export declare type NextComponentType<C extends BaseContext = NextPageContext, IP = {}, P = {}> = ComponentType<P> & {
    /**
     * Used for initial page load data population. Data returned from `getInitialProps` is serialized when server rendered.
     * Make sure to return plain `Object` without using `Date`, `Map`, `Set`.
     * @param ctx Context of `page`
     */
    getInitialProps?(context: C): IP | Promise<IP>;
};

从我的_app.tsx,我希望能够将Layout 添加到Component,例如:

  Component: {
    Layout?: React.FunctionComponent;
  };

有没有办法从AppProps 做到这一点,或者我需要先将AppPropsTypeLayout 扩展/相交,然后重新声明我自己的AppProps,它使用扩展的AppPropsType

【问题讨论】:

    标签: javascript typescript types extend


    【解决方案1】:

    起初,我为了阻止错误而遇到了这个丑陋的烂摊子:

    import { AppProps } from 'next/app'    
    
    export default function App({ Component, pageProps }: AppProps) {
      const RedeclaredAndHacky_Component = Component as any
      const Layout = RedeclaredAndHacky_Component.layoutProps?.Layout || Fr
      /* Rest of the function */
    }
    

    我不是很喜欢这个,所以我最终得到了更接近你描述的东西:

    import { NextComponentType, NextPageContext } from 'next'
    
    type AppProps = {
      pageProps: any
      Component: NextComponentType<NextPageContext, any, {}> & { layoutProps: any }
    }
    
    export default function App({ Component, pageProps }: AppProps) {
      const Layout = Component.layoutProps?.Layout || Shell
      /* Rest of the function */
    }
    

    【讨论】:

      【解决方案2】:

      我创建了一个自定义 AppProps Next 类型,这样我就可以编辑 Component 类型。

      interface CustomAppProps extends Omit<AppProps, "Component"> {
        Component: AppProps["Component"] & { Layout: JSX.Element };
      }
      

      最终结果将如下所示:

      import type { AppProps } from "next/app";
      
      interface CustomAppProps extends Omit<AppProps, "Component"> {
        Component: AppProps["Component"] & { Layout: JSX.Element };
      }
      
      function CustomApp({ Component, pageProps }: CustomAppProps) {
        return <Component {...pageProps} />;
      }
      
      export default CustomApp;
      

      【讨论】:

        猜你喜欢
        • 2021-02-11
        • 2021-07-11
        • 2022-09-24
        • 1970-01-01
        • 2019-07-20
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        • 2021-11-20
        相关资源
        最近更新 更多