使用可选属性扩展 TypeScript 类型

Rya*_*P13 5 javascript types extend typescript

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

应用程序属性:

export declare type AppProps<P = {}> = AppPropsType<Router, P>;
Run Code Online (Sandbox Code Playgroud)

应用程序属性类型:

export declare type AppPropsType<R extends NextRouter = NextRouter, P = {}> = AppInitialProps & {
    Component: NextComponentType<NextPageContext, any, P>;
    router: R;
    __N_SSG?: boolean;
    __N_SSP?: boolean;
};
Run Code Online (Sandbox Code Playgroud)

下一个组件类型:

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>;
};
Run Code Online (Sandbox Code Playgroud)

从我的角度来看_app.tsx,我希望能够添加Layout以下Component内容:

  Component: {
    Layout?: React.FunctionComponent;
  };
Run Code Online (Sandbox Code Playgroud)

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

Pab*_*zco 6

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

interface CustomAppProps extends Omit<AppProps, "Component"> {
  Component: AppProps["Component"] & { Layout: JSX.Element };
}
Run Code Online (Sandbox Code Playgroud)

最终结果将如下所示:

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;
Run Code Online (Sandbox Code Playgroud)


Tim*_*ley 3

起初,我用这个丑陋的混乱来阻止错误:

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 */
}
Run Code Online (Sandbox Code Playgroud)

我不太喜欢这个,所以我最终得到了更接近您所描述的内容:

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 */
}
Run Code Online (Sandbox Code Playgroud)