refactor: make entire project typecheck with root tsconfig (#7466)

This commit is contained in:
Joshua Chen 2022-05-23 12:54:25 +08:00 committed by GitHub
parent 89b0fff128
commit 2d94d575a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 74 additions and 36 deletions

View file

@ -35,7 +35,9 @@ const scoreEntry = (rawScore) => {
const createMarkdownTableRow = ({url, summary, reportUrl}) => const createMarkdownTableRow = ({url, summary, reportUrl}) =>
[ [
`| [${new URL(url).pathname}](${url})`, `| [${new URL(url).pathname}](${url})`,
...Object.keys(summaryKeys).map((k) => scoreEntry(summary[k])), .../** @type {(keyof LighthouseSummary)[]} */ (
Object.keys(summaryKeys)
).map((k) => scoreEntry(summary[k])),
`[Report](${reportUrl}) |`, `[Report](${reportUrl}) |`,
].join(' | '); ].join(' | ');
@ -54,8 +56,10 @@ const createMarkdownTableHeader = () => [
const createLighthouseReport = ({results, links}) => { const createLighthouseReport = ({results, links}) => {
const tableHeader = createMarkdownTableHeader(); const tableHeader = createMarkdownTableHeader();
const tableBody = results.map((result) => { const tableBody = results.map((result) => {
const testUrl = Object.keys(links).find((key) => key === result.url); const testUrl = /** @type {string} */ (
const reportPublicUrl = links[testUrl]; Object.keys(links).find((key) => key === result.url)
);
const reportPublicUrl = /** @type {string} */ (links[testUrl]);
return createMarkdownTableRow({ return createMarkdownTableRow({
url: testUrl, url: testUrl,

View file

@ -3,7 +3,6 @@
"references": [{"path": "./tsconfig.build.json"}], "references": [{"path": "./tsconfig.build.json"}],
"compilerOptions": { "compilerOptions": {
"noEmit": true, "noEmit": true,
"allowJs": true,
"module": "esnext", "module": "esnext",
"rootDir": "." "rootDir": "."
}, },

View file

@ -4,7 +4,6 @@
"compilerOptions": { "compilerOptions": {
"noEmit": true, "noEmit": true,
"module": "esnext", "module": "esnext",
"allowJs": true,
"rootDir": "." "rootDir": "."
}, },
"include": ["bin"], "include": ["bin"],

View file

@ -34,8 +34,9 @@ const StableEmptyObject = {};
// In blog-only mode, docs hooks are still used by the theme. We need a fail- // In blog-only mode, docs hooks are still used by the theme. We need a fail-
// safe fallback when the docs plugin is not in use // safe fallback when the docs plugin is not in use
export const useAllDocsData = (): {[pluginId: string]: GlobalPluginData} => export const useAllDocsData = (): {[pluginId: string]: GlobalPluginData} =>
useAllPluginInstancesData('docusaurus-plugin-content-docs') ?? (useAllPluginInstancesData('docusaurus-plugin-content-docs') as {
StableEmptyObject; [pluginId: string]: GlobalPluginData;
}) ?? StableEmptyObject;
export const useDocsData = (pluginId: string | undefined): GlobalPluginData => export const useDocsData = (pluginId: string | undefined): GlobalPluginData =>
usePluginData('docusaurus-plugin-content-docs', pluginId, { usePluginData('docusaurus-plugin-content-docs', pluginId, {

View file

@ -7,20 +7,12 @@
import {createStorageSlot} from '@docusaurus/theme-common'; import {createStorageSlot} from '@docusaurus/theme-common';
declare global {
namespace NodeJS {
interface ProcessEnv {
PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES: (keyof typeof OfflineModeActivationStrategiesImplementations)[];
}
}
}
// First: read the env variables (provided by Webpack) // First: read the env variables (provided by Webpack)
/* eslint-disable prefer-destructuring */ /* eslint-disable prefer-destructuring */
const PWA_SERVICE_WORKER_URL = process.env.PWA_SERVICE_WORKER_URL; const PWA_SERVICE_WORKER_URL = process.env.PWA_SERVICE_WORKER_URL;
const PWA_RELOAD_POPUP = process.env.PWA_RELOAD_POPUP; const PWA_RELOAD_POPUP = process.env.PWA_RELOAD_POPUP;
const PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES = const PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES = process.env
process.env.PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES; .PWA_OFFLINE_MODE_ACTIVATION_STRATEGIES as unknown as (keyof typeof OfflineModeActivationStrategiesImplementations)[];
const PWA_DEBUG = process.env.PWA_DEBUG; const PWA_DEBUG = process.env.PWA_DEBUG;
/* eslint-enable prefer-destructuring */ /* eslint-enable prefer-destructuring */
@ -77,7 +69,7 @@ async function isAppInstalledEventFired() {
declare global { declare global {
interface Navigator { interface Navigator {
getInstalledRelatedApps: () => Promise<{platform: string}[]>; getInstalledRelatedApps: () => Promise<{platform: string}[]>;
connection: {saveData: boolean}; connection: {effectiveType: string; saveData: boolean};
} }
} }

View file

@ -4,8 +4,7 @@
"compilerOptions": { "compilerOptions": {
"module": "esnext", "module": "esnext",
"noEmit": true, "noEmit": true,
"checkJs": true, "checkJs": true
"allowJs": true
}, },
"include": ["update.mjs"] "include": ["update.mjs"]
} }

View file

@ -6,7 +6,6 @@
], ],
"compilerOptions": { "compilerOptions": {
"noEmit": true, "noEmit": true,
"allowJs": true,
"checkJs": true, "checkJs": true,
"rootDir": ".", "rootDir": ".",
"module": "esnext" "module": "esnext"

View file

@ -11,6 +11,8 @@
"jsx": "react-native", "jsx": "react-native",
"importHelpers": true, "importHelpers": true,
"noEmitHelpers": true, "noEmitHelpers": true,
// Will be overridden in every project
"module": "esnext",
// Avoid accidentally using this config to build // Avoid accidentally using this config to build
"noEmit": true, "noEmit": true,
@ -46,7 +48,15 @@
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"isolatedModules": true, "isolatedModules": true,
"allowJs": true,
"skipLibCheck": true // @types/webpack and webpack/types.d.ts are not the same thing "skipLibCheck": true // @types/webpack and webpack/types.d.ts are not the same thing
}, },
"exclude": ["node_modules", "**/lib/**/*"] "exclude": [
"node_modules",
"**/lib/**/*",
"website/**",
"**/__mocks__/**/*",
"examples/**",
"packages/create-docusaurus/templates/**"
]
} }

View file

@ -13,7 +13,7 @@ import CodeBlock from '@theme/CodeBlock';
type ContextValue = { type ContextValue = {
name: string; name: string;
time: string; time: string | undefined;
}; };
const Context = React.createContext<ContextValue | null>(null); const Context = React.createContext<ContextValue | null>(null);
@ -44,7 +44,7 @@ function useStableVersion(): string {
const allVersions = useVersions('default'); const allVersions = useVersions('default');
const lastVersion = ( const lastVersion = (
allVersions.find((v) => v.name !== 'current') ?? allVersions[0] allVersions.find((v) => v.name !== 'current') ?? allVersions[0]!
).name; ).name;
return preferredVersion && preferredVersion !== 'current' return preferredVersion && preferredVersion !== 'current'
? preferredVersion ? preferredVersion

View file

@ -26,7 +26,7 @@ function getNextBetaVersionName() {
const expectedPrefix = '2.0.0-beta.'; const expectedPrefix = '2.0.0-beta.';
const lastReleasedVersion = versions[0]; const lastReleasedVersion = versions[0];
if (!lastReleasedVersion.includes(expectedPrefix)) { if (!lastReleasedVersion || !lastReleasedVersion.includes(expectedPrefix)) {
throw new Error( throw new Error(
'this code is only meant to be used during the 2.0 beta phase.', 'this code is only meant to be used during the 2.0 beta phase.',
); );

View file

@ -67,9 +67,10 @@ const APITableRowComp = React.forwardRef(APITableRow);
* should be generally correct in the MDX context. * should be generally correct in the MDX context.
*/ */
export default function APITable({children, name}: Props): JSX.Element { export default function APITable({children, name}: Props): JSX.Element {
const [thead, tbody] = React.Children.toArray( const [thead, tbody] = React.Children.toArray(children.props.children) as [
children.props.children, ReactElement,
) as ReactElement[]; ReactElement,
];
const highlightedRow = useRef<HTMLTableRowElement>(null); const highlightedRow = useRef<HTMLTableRowElement>(null);
useEffect(() => { useEffect(() => {
highlightedRow.current?.focus(); highlightedRow.current?.focus();

View file

@ -250,7 +250,7 @@ export default function ColorGenerator(): JSX.Element {
setShades({ setShades({
...shades, ...shades,
[variableName]: { [variableName]: {
...shades[variableName], ...shades[variableName]!,
adjustmentInput: event.target.value, adjustmentInput: event.target.value,
adjustment: Number.isNaN(newValue) adjustment: Number.isNaN(newValue)
? adjustment ? adjustment

View file

@ -23,7 +23,7 @@ function PackageJson() {
// Only happens in deploy preview / local dev, but still nice // Only happens in deploy preview / local dev, but still nice
const versionName = const versionName =
latestVersion.name === 'current' && allVersions.length > 1 latestVersion.name === 'current' && allVersions.length > 1
? allVersions[1].name ? allVersions[1]!.name
: latestVersion.name; : latestVersion.name;
return ( return (
<CodeBlock language="json" title="package.json">{`{ <CodeBlock language="json" title="package.json">{`{

View file

@ -101,7 +101,7 @@ function MigrationAnnouncement() {
function TweetsSection() { function TweetsSection() {
const tweetColumns: Array<Array<TweetItem>> = [[], [], []]; const tweetColumns: Array<Array<TweetItem>> = [[], [], []];
Tweets.filter((tweet) => tweet.showOnHomepage).forEach((tweet, i) => Tweets.filter((tweet) => tweet.showOnHomepage).forEach((tweet, i) =>
tweetColumns[i % 3].push(tweet), tweetColumns[i % 3]!.push(tweet),
); );
return ( return (

10
website/src/theme/theme.d.ts vendored Normal file
View file

@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
declare module '@theme-original/ColorModeToggle' {
export {default} from '@theme/ColorModeToggle';
}

View file

@ -85,12 +85,14 @@ export const darkStorage = createStorageSlot('ifm-theme-colors-dark', {
persistence: 'sessionStorage', persistence: 'sessionStorage',
}); });
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function getAdjustedColors(
export function getAdjustedColors(shades: Shades, baseColor: string) { shades: Shades,
baseColor: string,
): (Shades[string] & {variableName: string; hex: string})[] {
return Object.keys(shades).map((shade) => ({ return Object.keys(shades).map((shade) => ({
...shades[shade], ...shades[shade]!,
variableName: shade, variableName: shade,
hex: Color(baseColor).darken(shades[shade].adjustment).hex(), hex: Color(baseColor).darken(shades[shade]!.adjustment).hex(),
})); }));
} }

View file

@ -5,13 +5,35 @@
"lib": ["DOM", "ESNext"], "lib": ["DOM", "ESNext"],
"baseUrl": ".", "baseUrl": ".",
"resolveJsonModule": true, "resolveJsonModule": true,
// Duplicated from the root config, because TS does not support extending
// multiple configs and we want to dogfood the @tsconfig/docusaurus one
"allowUnreachableCode": false,
"exactOptionalPropertyTypes": false,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": false,
"noUncheckedIndexedAccess": true,
"strict": true, "strict": true,
"alwaysStrict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"useUnknownInCatchVariables": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"importsNotUsedAsValues": "remove",
// This is important. We run `yarn tsc` in website so we can catch issues // This is important. We run `yarn tsc` in website so we can catch issues
// with our declaration files (mostly names that are forgotten to be // with our declaration files (mostly names that are forgotten to be
// imported, invalid semantics...). Because we don't have end-to-end type // imported, invalid semantics...). Because we don't have end-to-end type
// tests, removing this would make things much harder to catch. // tests, removing this would make things much harder to catch.
"skipLibCheck": false, "skipLibCheck": false,
"types": ["@types/jest"] "types": ["jest"]
}, },
"exclude": ["src/sw.js"] "exclude": ["src/sw.js"]
} }