From 88de99b8afe242ef67c04e38494c0c3663a9e1c3 Mon Sep 17 00:00:00 2001 From: josefaidt Date: Wed, 31 Jul 2024 11:28:49 -0700 Subject: [PATCH] add type-checking to MDX files, narrow InlineFilter type --- mdx-components.tsx | 108 +++++++++++++++++--------- src/components/InlineFilter/index.tsx | 3 +- tsconfig.json | 7 +- 3 files changed, 79 insertions(+), 39 deletions(-) diff --git a/mdx-components.tsx b/mdx-components.tsx index 88e069e9dd1..39dad01d5b1 100644 --- a/mdx-components.tsx +++ b/mdx-components.tsx @@ -1,5 +1,11 @@ import * as React from 'react'; -import type { MDXComponents } from 'mdx/types'; +import type { Metadata } from 'next'; +import type { + MDXComponents as BaseMDXComponents, + MDXProps as BaseMDXProps +} from 'mdx/types'; +import type { PageNode } from './src/directory/directory'; +import type { Platform } from './src/data/platforms'; import ExportedImage from 'next-image-export-optimizer'; import InlineFilter from './src/components/InlineFilter'; import { YoutubeEmbed } from './src/components/YoutubeEmbed'; @@ -34,43 +40,71 @@ const MDXHeading4 = (props) => ; const MDXHeading5 = (props) => ; const MDXHeading6 = (props) => ; -export function useMDXComponents(components: MDXComponents): MDXComponents { - return { - // Map markdown elements to custom components - a: MDXLink, - h1: MDXHeading1, - h2: MDXHeading2, - h3: MDXHeading3, - h4: MDXHeading4, - h5: MDXHeading5, - h6: MDXHeading6, - pre: (preProps) => { - const props = preToCodeBlock(preProps); - if (props) { - return ; - } - return
;
-    },
-    img: ResponsiveImage,
-    table: MDXTable,
+const components = {
+  // Map markdown elements to custom components
+  a: MDXLink,
+  h1: MDXHeading1,
+  h2: MDXHeading2,
+  h3: MDXHeading3,
+  h4: MDXHeading4,
+  h5: MDXHeading5,
+  h6: MDXHeading6,
+  pre: (preProps) => {
+    const props = preToCodeBlock(preProps);
+    if (props) {
+      return ;
+    }
+    return 
;
+  },
+  img: ResponsiveImage,
+  table: MDXTable,
+
+  // Make common custom components available to content authors
+  Accordion,
+  Block,
+  BlockSwitcher,
+  Callout,
+  Fragments,
+  InlineFilter,
+  MigrationAlert,
+  YoutubeEmbed,
+  Overview,
+  ExternalLink,
+  ExternalLinkButton,
+  InternalLinkButton,
+  Grid,
+  Columns,
+  Video,
+  View
+} satisfies BaseMDXComponents;
+
+/**
+ * MDX Page metadata
+ */
+type MDXPageMeta = Metadata & {
+  platforms: Platform[];
+};
+
+/**
+ * Type for Next.js's getStaticProps return in MDX pages
+ * this is needed to satisfy the type-check for 's childPageNodes
+ */
+type MDXGetStaticPropsResult = {
+  meta: MDXPageMeta;
+  childPageNodes?: PageNode[];
+};
 
-    // Make common custom components available to content authors
-    Accordion,
-    Block,
-    BlockSwitcher,
-    Callout,
-    Fragments,
-    InlineFilter,
-    MigrationAlert,
-    YoutubeEmbed,
-    Overview,
-    ExternalLink,
-    ExternalLinkButton,
-    InternalLinkButton,
-    Grid,
-    Columns,
-    Video,
-    View,
+/**
+ * Declare types in the global scope for MDX to type-check components and function return statements
+ */
+declare global {
+  type MDXProvidedComponents = typeof components;
+  type MDXProps = BaseMDXProps & MDXGetStaticPropsResult;
+}
+
+export function useMDXComponents(_components: BaseMDXComponents) {
+  return {
+    ..._components,
     ...components
   };
 }
diff --git a/src/components/InlineFilter/index.tsx b/src/components/InlineFilter/index.tsx
index c7b20ed6d99..4493655e300 100644
--- a/src/components/InlineFilter/index.tsx
+++ b/src/components/InlineFilter/index.tsx
@@ -1,9 +1,10 @@
+import type { Platform } from '@/data/platforms';
 import { Fragment } from 'react';
 import FilterChildren from '../FilterChildren';
 
 type InlineFilterProps = {
   children: React.ReactNode;
-  filters: string[];
+  filters: Platform[];
 };
 
 export default function InlineFilter({ filters, children }: InlineFilterProps) {
diff --git a/tsconfig.json b/tsconfig.json
index 2e464bf1ffc..844876668c7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -27,10 +27,15 @@
   "extends": "./tsconfig.base.json",
   "include": [
     "next-env.d.ts",
+    "mdx-components.tsx",
     "src/**/*.ts",
     "src/**/*.tsx",
+    "src/**/*.mdx",
     "tasks",
     "adobe.d.ts",
     "jest.setup.ts"
-  ]
+  ],
+  "mdx": {
+    "checkMdx": true
+  }
 }