refactor(v2): correct client types and type aliases (#4451)

This commit is contained in:
Armano 2021-03-19 11:32:38 +01:00 committed by GitHub
parent 291a72fbae
commit 15107ee099
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 128 additions and 97 deletions

View file

@ -132,6 +132,12 @@ module.exports = {
'header/header': OFF, 'header/header': OFF,
}, },
}, },
{
files: ['*.d.ts'],
rules: {
'import/no-duplicates': OFF,
},
},
{ {
files: ['*.js'], files: ['*.js'],
rules: { rules: {

View file

@ -14,7 +14,9 @@
"devDependencies": { "devDependencies": {
"@types/react": "*", "@types/react": "*",
"@types/react-helmet": "*", "@types/react-helmet": "*",
"@types/react-router-dom": "*" "@types/react-loadable": "*",
"@types/react-router-dom": "*",
"@types/react-router-config": "*"
}, },
"license": "MIT" "license": "MIT"
} }

View file

@ -69,16 +69,30 @@ declare module '@theme-original/*';
declare module '@docusaurus/*'; declare module '@docusaurus/*';
declare module '@docusaurus/Head' { declare module '@docusaurus/Head' {
const helmet: typeof import('react-helmet').Helmet; import type {HelmetProps} from 'react-helmet';
export default helmet; import type {ReactNode} from 'react';
export type HeadProps = HelmetProps & {children: ReactNode};
const Head: (props: HeadProps) => JSX.Element;
export default Head;
} }
declare module '@docusaurus/Link' { declare module '@docusaurus/Link' {
import type {ReactNode} from 'react';
type RRLinkProps = Partial<import('react-router-dom').LinkProps>; type RRLinkProps = Partial<import('react-router-dom').LinkProps>;
type LinkProps = RRLinkProps & { export type LinkProps = RRLinkProps & {
to?: string; readonly isNavLink?: boolean;
activeClassName?: string; readonly to?: string;
isNavLink?: boolean; readonly href?: string;
readonly activeClassName?: string;
readonly children?: ReactNode;
readonly isActive?: (match: any, location: any) => boolean;
readonly autoAddBaseUrl?: boolean;
// escape hatch in case broken links check is annoying for a specific link
readonly 'data-noBrokenLinkCheck'?: boolean;
}; };
const Link: (props: LinkProps) => JSX.Element; const Link: (props: LinkProps) => JSX.Element;
export default Link; export default Link;
@ -125,31 +139,33 @@ declare module '@docusaurus/Translate' {
InterpolateValues, InterpolateValues,
} from '@docusaurus/Interpolate'; } from '@docusaurus/Interpolate';
type TranslateProps<Str extends string> = InterpolateProps<Str> & { export type TranslateParam<Str extends string> = Partial<
id?: string; InterpolateProps<Str>
description?: string; > & {
};
export default function Translate<Str extends string>(
props: TranslateProps<Str>,
): JSX.Element;
export function translate<Str extends string>(
param: {
message: Str; message: Str;
id?: string; id?: string;
description?: string; description?: string;
}, values?: InterpolateValues<Str, string | number>;
};
export function translate<Str extends string>(
param: TranslateParam<Str>,
values?: InterpolateValues<Str, string | number>, values?: InterpolateValues<Str, string | number>,
): string; ): string;
export type TranslateProps<Str extends string> = InterpolateProps<Str> & {
id?: string;
description?: string;
};
export default function Translate<Str extends string>(
props: TranslateProps<Str>,
): JSX.Element;
} }
declare module '@docusaurus/router' { declare module '@docusaurus/router' {
export const Redirect: (props: {to: string}) => import('react').Component; // eslint-disable-next-line import/no-extraneous-dependencies
export function matchPath( export * from 'react-router-dom';
pathname: string,
opts: {path?: string; exact?: boolean; strict?: boolean},
): boolean;
export function useLocation(): Location;
} }
declare module '@docusaurus/useDocusaurusContext' { declare module '@docusaurus/useDocusaurusContext' {
@ -157,9 +173,20 @@ declare module '@docusaurus/useDocusaurusContext' {
} }
declare module '@docusaurus/useBaseUrl' { declare module '@docusaurus/useBaseUrl' {
export type BaseUrlOptions = {
forcePrependBaseUrl?: boolean;
absolute?: boolean;
};
export type BaseUrlUtils = {
withBaseUrl: (url: string, options?: BaseUrlOptions) => string;
};
export function useBaseUrlUtils(): BaseUrlUtils;
export default function useBaseUrl( export default function useBaseUrl(
relativePath: string | undefined, relativePath: string | undefined,
opts?: {absolute?: true; forcePrependBaseUrl?: true}, opts?: BaseUrlOptions,
): string; ): string;
} }
@ -173,6 +200,16 @@ declare module '@docusaurus/ExecutionEnvironment' {
export default ExecutionEnvironment; export default ExecutionEnvironment;
} }
declare module '@docusaurus/ComponentCreator' {
import type Loadable from 'react-loadable';
function ComponentCreator(
path: string,
hash: string,
): ReturnType<typeof Loadable>;
export default ComponentCreator;
}
declare module '@docusaurus/BrowserOnly' { declare module '@docusaurus/BrowserOnly' {
export type Props = { export type Props = {
children?: () => JSX.Element; children?: () => JSX.Element;
@ -187,6 +224,31 @@ declare module '@docusaurus/isInternalUrl' {
export default function isInternalUrl(url?: string): boolean; export default function isInternalUrl(url?: string): boolean;
} }
declare module '@docusaurus/Noop' {
export default function (): null;
}
declare module '@docusaurus/renderRoutes' {
// eslint-disable-next-line import/no-extraneous-dependencies
import {renderRoutes} from 'react-router-config';
export default renderRoutes;
}
declare module '@docusaurus/useGlobalData' {
export function useAllPluginInstancesData<T = unknown>(
pluginName: string,
): Record<string, T>;
export function usePluginData<T = unknown>(
pluginName: string,
pluginId?: string,
): T;
function useGlobalData(): Record<string, any>;
export default useGlobalData;
}
declare module '*.module.css' { declare module '*.module.css' {
const classes: {readonly [key: string]: string}; const classes: {readonly [key: string]: string};
export default classes; export default classes;

View file

@ -100,7 +100,7 @@ declare module '@theme/DocPage' {
readonly route: { readonly route: {
readonly path: string; readonly path: string;
readonly component: () => JSX.Element; readonly component: () => JSX.Element;
readonly routes: readonly DocumentRoute[]; readonly routes: DocumentRoute[];
}; };
}; };

View file

@ -259,7 +259,9 @@ declare module '@theme/Layout' {
} }
declare module '@theme/LayoutHead' { declare module '@theme/LayoutHead' {
import type {Props} from '@theme/Layout'; import type {Props as LayoutProps} from '@theme/Layout';
export type Props = Omit<LayoutProps, 'children'>;
const LayoutHead: (props: Props) => JSX.Element; const LayoutHead: (props: Props) => JSX.Element;
export default LayoutHead; export default LayoutHead;

View file

@ -12,6 +12,8 @@ import routesChunkNames from '@generated/routesChunkNames';
import registry from '@generated/registry'; import registry from '@generated/registry';
import flat from '../flat'; import flat from '../flat';
type OptsLoader = Record<string, typeof registry[keyof typeof registry][0]>;
function ComponentCreator( function ComponentCreator(
path: string, path: string,
hash: string, hash: string,
@ -28,7 +30,7 @@ function ComponentCreator(
const chunkNames = routesChunkNames[chunkNamesKey]; const chunkNames = routesChunkNames[chunkNamesKey];
const optsModules: string[] = []; const optsModules: string[] = [];
const optsWebpack: string[] = []; const optsWebpack: string[] = [];
const optsLoader = {}; const optsLoader: OptsLoader = {};
/* Prepare opts data that react-loadable needs /* Prepare opts data that react-loadable needs
https://github.com/jamiebuilds/react-loadable#declaring-which-modules-are-being-loaded https://github.com/jamiebuilds/react-loadable#declaring-which-modules-are-being-loaded

View file

@ -5,10 +5,9 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import React, {ReactNode} from 'react'; import React from 'react';
import {Helmet, HelmetProps} from 'react-helmet'; import {Helmet} from 'react-helmet';
import type {HeadProps} from '@docusaurus/Head';
type HeadProps = HelmetProps & {children: ReactNode};
function Head(props: HeadProps): JSX.Element { function Head(props: HeadProps): JSX.Element {
return <Helmet {...props} />; return <Helmet {...props} />;

View file

@ -6,6 +6,11 @@
*/ */
import React, {ReactNode} from 'react'; import React, {ReactNode} from 'react';
import type {
InterpolateProps,
InterpolateValues,
ExtractInterpolatePlaceholders,
} from '@docusaurus/Interpolate';
/* /*
Minimal implementation of a React interpolate component. Minimal implementation of a React interpolate component.
@ -16,16 +21,6 @@ More details here: https://github.com/facebook/docusaurus/pull/4295
const ValueRegexp = /{\w+}/g; const ValueRegexp = /{\w+}/g;
const ValueFoundMarker = '{}'; // does not care much const ValueFoundMarker = '{}'; // does not care much
// TODO use TS template literal feature to make values typesafe!
// (requires upgrading TS first)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type ExtractInterpolatePlaceholders<Str extends string> = string;
type InterpolateValues<Str extends string, Value extends ReactNode> = Record<
ExtractInterpolatePlaceholders<Str>,
Value
>;
// TS function overload: if all the values are plain strings, then interpolate returns a simple string // TS function overload: if all the values are plain strings, then interpolate returns a simple string
export function interpolate<Str extends string>( export function interpolate<Str extends string>(
text: Str, text: Str,
@ -93,11 +88,6 @@ export function interpolate<Str extends string, Value extends ReactNode>(
} }
} }
export type InterpolateProps<Str extends string> = {
children: Str;
values?: InterpolateValues<Str, ReactNode>;
};
export default function Interpolate<Str extends string>({ export default function Interpolate<Str extends string>({
children, children,
values, values,

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import React, {ReactNode, useEffect, useRef} from 'react'; import React, {useEffect, useRef} from 'react';
import {NavLink, Link as RRLink} from 'react-router-dom'; import {NavLink, Link as RRLink} from 'react-router-dom';
import isInternalUrl from './isInternalUrl'; import isInternalUrl from './isInternalUrl';
@ -13,28 +13,15 @@ import ExecutionEnvironment from './ExecutionEnvironment';
import {useLinksCollector} from '../LinksCollector'; import {useLinksCollector} from '../LinksCollector';
import {useBaseUrlUtils} from './useBaseUrl'; import {useBaseUrlUtils} from './useBaseUrl';
import type {LinkProps} from '@docusaurus/Link';
import type docusaurus from '../docusaurus';
declare global { declare global {
interface Window { interface Window {
docusaurus: { docusaurus: typeof docusaurus;
prefetch: (routePath: string) => boolean;
preload: (routePath: string) => boolean;
};
} }
} }
interface Props {
readonly isNavLink?: boolean;
readonly to?: string;
readonly href?: string;
readonly activeClassName?: string;
readonly children?: ReactNode;
readonly isActive?: () => boolean;
readonly autoAddBaseUrl?: boolean;
// escape hatch in case broken links check is annoying for a specific link
readonly 'data-noBrokenLinkCheck'?: boolean;
}
// TODO all this wouldn't be necessary if we used ReactRouter basename feature // TODO all this wouldn't be necessary if we used ReactRouter basename feature
// We don't automatically add base urls to all links, // We don't automatically add base urls to all links,
// only the "safe" ones, starting with / (like /docs/introduction) // only the "safe" ones, starting with / (like /docs/introduction)
@ -51,7 +38,7 @@ function Link({
'data-noBrokenLinkCheck': noBrokenLinkCheck, 'data-noBrokenLinkCheck': noBrokenLinkCheck,
autoAddBaseUrl = true, autoAddBaseUrl = true,
...props ...props
}: Props): JSX.Element { }: LinkProps): JSX.Element {
const {withBaseUrl} = useBaseUrlUtils(); const {withBaseUrl} = useBaseUrlUtils();
const linksCollector = useLinksCollector(); const linksCollector = useLinksCollector();
@ -92,8 +79,8 @@ function Link({
const IOSupported = ExecutionEnvironment.canUseIntersectionObserver; const IOSupported = ExecutionEnvironment.canUseIntersectionObserver;
let io; let io: IntersectionObserver;
const handleIntersection = (el, cb) => { const handleIntersection = (el: HTMLAnchorElement, cb: () => void) => {
io = new window.IntersectionObserver((entries) => { io = new window.IntersectionObserver((entries) => {
entries.forEach((entry) => { entries.forEach((entry) => {
if (el === entry.target) { if (el === entry.target) {
@ -112,7 +99,7 @@ function Link({
io.observe(el); io.observe(el);
}; };
const handleRef = (ref) => { const handleRef = (ref: HTMLAnchorElement | null) => {
if (IOSupported && ref && isInternal) { if (IOSupported && ref && isInternal) {
// If IO supported and element reference found, setup Observer functionality. // If IO supported and element reference found, setup Observer functionality.
handleIntersection(ref, () => { handleIntersection(ref, () => {

View file

@ -8,9 +8,9 @@
import React from 'react'; import React from 'react';
import Interpolate, { import Interpolate, {
interpolate, interpolate,
InterpolateProps,
InterpolateValues, InterpolateValues,
} from '@docusaurus/Interpolate'; } from '@docusaurus/Interpolate';
import type {TranslateParam, TranslateProps} from '@docusaurus/Translate';
// Can't read it from context, due to exposing imperative API // Can't read it from context, due to exposing imperative API
import codeTranslations from '@generated/codeTranslations'; import codeTranslations from '@generated/codeTranslations';
@ -25,12 +25,6 @@ function getLocalizedMessage({
return codeTranslations[id ?? message] ?? message; return codeTranslations[id ?? message] ?? message;
} }
export type TranslateParam<Str extends string> = {
message: Str;
id?: string;
description?: string;
values?: InterpolateValues<Str, string | number>;
};
// Imperative translation API is useful for some edge-cases: // Imperative translation API is useful for some edge-cases:
// - translating page titles (meta) // - translating page titles (meta)
// - translating string props (input placeholders, image alt, aria labels...) // - translating string props (input placeholders, image alt, aria labels...)
@ -42,11 +36,6 @@ export function translate<Str extends string>(
return interpolate(localizedMessage, values); return interpolate(localizedMessage, values);
} }
export type TranslateProps<Str extends string> = InterpolateProps<Str> & {
id?: string;
description?: string;
};
// Maybe we'll want to improve this component with additional features // Maybe we'll want to improve this component with additional features
// Like toggling a translation mode that adds a little translation button near the text? // Like toggling a translation mode that adds a little translation button near the text?
export default function Translate<Str extends string>({ export default function Translate<Str extends string>({

View file

@ -7,11 +7,7 @@
import useDocusaurusContext from './useDocusaurusContext'; import useDocusaurusContext from './useDocusaurusContext';
import {hasProtocol} from './isInternalUrl'; import {hasProtocol} from './isInternalUrl';
import type {BaseUrlOptions, BaseUrlUtils} from '@docusaurus/useBaseUrl';
type BaseUrlOptions = Partial<{
forcePrependBaseUrl: boolean;
absolute: boolean;
}>;
function addBaseUrl( function addBaseUrl(
siteUrl: string | undefined, siteUrl: string | undefined,
@ -45,10 +41,6 @@ function addBaseUrl(
return absolute ? siteUrl + basePath : basePath; return absolute ? siteUrl + basePath : basePath;
} }
export type BaseUrlUtils = {
withBaseUrl: (url: string, options?: BaseUrlOptions) => string;
};
export function useBaseUrlUtils(): BaseUrlUtils { export function useBaseUrlUtils(): BaseUrlUtils {
const { const {
siteConfig: {baseUrl = '/', url: siteUrl} = {}, siteConfig: {baseUrl = '/', url: siteUrl} = {},

View file

@ -3629,18 +3629,18 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-loadable@^5.5.3": "@types/react-loadable@*", "@types/react-loadable@^5.5.3":
version "5.5.3" version "5.5.4"
resolved "https://registry.yarnpkg.com/@types/react-loadable/-/react-loadable-5.5.3.tgz#65d50a6f9f7ff62513010bd6a460ed60ba58ca7d" resolved "https://registry.yarnpkg.com/@types/react-loadable/-/react-loadable-5.5.4.tgz#9bfb31e1299e9a3b23ea6cae437fa8813afde544"
integrity sha512-BRzQhbMo5CjfxFU2tmmBNh16QqKUwNiaX0vflCwIVPVG8g/pCOyJ3rOdSPo4m+TPS7C9q/TupaqYXXTMtFoyng== integrity sha512-otKcjNCfVUzdBMdwOqFITTmBruIXw6GeoZitTBvJ6BMrif8Utu2JLy42GWukNnYI7ewJdncUCooz5Y/1dBz4+w==
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/webpack" "*" "@types/webpack" "*"
"@types/react-router-config@^5.0.1": "@types/react-router-config@*", "@types/react-router-config@^5.0.1":
version "5.0.1" version "5.0.2"
resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.1.tgz#54da8418190ee47484dee279975e2b8038fb8b5d" resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.2.tgz#4d3b52e71ed363a1976a12321e67b09a99ad6d10"
integrity sha512-D4srFL4XP21GjWWnM7mL8j+Nrrw13pc2TYr57WTHJxU9YTxnrXL7p1iqGtwecgwhyeXJSm4WrGwq0SOgSALVbA== integrity sha512-WOSetDV3YPxbkVJAdv/bqExJjmcdCi/vpCJh3NfQOy1X15vHMSiMioXIcGekXDJJYhqGUMDo9e337mh508foAA==
dependencies: dependencies:
"@types/history" "*" "@types/history" "*"
"@types/react" "*" "@types/react" "*"