docusaurus/assets/js/a05ec3a8.28b5ce90.js
2025-03-13 09:57:12 +00:00

1 line
No EOL
14 KiB
JavaScript

"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([["47749"],{70531:function(e,n,t){t.r(n),t.d(n,{frontMatter:()=>a,default:()=>h,contentTitle:()=>l,assets:()=>u,toc:()=>p,metadata:()=>s});var s=JSON.parse('{"id":"typescript-support","title":"TypeScript Support","description":"Docusaurus is written in TypeScript and provides first-class TypeScript support.","source":"@site/docs/typescript-support.mdx","sourceDirName":".","slug":"/typescript-support","permalink":"/docs/typescript-support","draft":false,"unlisted":false,"editUrl":"https://github.com/facebook/docusaurus/edit/main/website/docs/typescript-support.mdx","tags":[],"version":"current","lastUpdatedBy":"pedenys","lastUpdatedAt":1741859625000,"frontMatter":{"description":"Docusaurus is written in TypeScript and provides first-class TypeScript support."},"sidebar":"docs","previous":{"title":"Playground","permalink":"/docs/playground"},"next":{"title":"Guides","permalink":"/docs/category/guides"}}'),r=t(85893),i=t(80980),o=t(15398),c=t(58636);let a={description:"Docusaurus is written in TypeScript and provides first-class TypeScript support."},l="TypeScript Support",u={},p=[{value:"Initialization",id:"initialization",level:2},{value:"Setup",id:"setup",level:2},{value:"Typing the config file",id:"typing-config",level:2},{value:"Swizzling TypeScript theme components",id:"swizzling-typescript-theme-components",level:2}];function d(e){let n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,i.a)(),...e.components},{Details:t}=n;return t||function(e,n){throw Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"typescript-support",children:"TypeScript Support"})}),"\n",(0,r.jsx)(n.p,{children:"Docusaurus is written in TypeScript and provides first-class TypeScript support."}),"\n",(0,r.jsxs)(n.p,{children:["The minimum required version is ",(0,r.jsx)(n.strong,{children:"TypeScript 5.1"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"initialization",children:"Initialization"}),"\n",(0,r.jsxs)(n.p,{children:["Docusaurus supports writing and using TypeScript theme components. If the init template provides a TypeScript variant, you can directly ",(0,r.jsx)(n.a,{href:"/docs/installation#scaffold-project-website",children:"initialize a site"})," with full TypeScript support by using the ",(0,r.jsx)(n.code,{children:"--typescript"})," flag."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npx create-docusaurus@latest my-website classic --typescript\n"})}),"\n",(0,r.jsx)(n.p,{children:"Below are some guides on how to migrate an existing project to TypeScript."}),"\n",(0,r.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,r.jsx)(n.p,{children:"Add the following packages to your project:"}),"\n",(0,r.jsxs)(o.Z,{groupId:"npm2yarn",children:[(0,r.jsx)(c.Z,{value:"npm",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm install --save-dev typescript @docusaurus/module-type-aliases @docusaurus/tsconfig @docusaurus/types\n"})})}),(0,r.jsx)(c.Z,{value:"yarn",label:"Yarn",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"yarn add --dev typescript @docusaurus/module-type-aliases @docusaurus/tsconfig @docusaurus/types\n"})})}),(0,r.jsx)(c.Z,{value:"pnpm",label:"pnpm",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"pnpm add --save-dev typescript @docusaurus/module-type-aliases @docusaurus/tsconfig @docusaurus/types\n"})})}),(0,r.jsx)(c.Z,{value:"bun",label:"Bun",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"bun add --dev typescript @docusaurus/module-type-aliases @docusaurus/tsconfig @docusaurus/types\n"})})})]}),"\n",(0,r.jsxs)(n.p,{children:["Then add ",(0,r.jsx)(n.code,{children:"tsconfig.json"})," to your project root with the following content:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",metastring:'title="tsconfig.json"',children:'{\n "extends": "@docusaurus/tsconfig",\n "compilerOptions": {\n "baseUrl": "."\n }\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Docusaurus doesn't use this ",(0,r.jsx)(n.code,{children:"tsconfig.json"})," to compile your project. It is added just for a nicer Editor experience, although you can choose to run ",(0,r.jsx)(n.code,{children:"tsc"})," to type check your code for yourself or on CI."]}),"\n",(0,r.jsx)(n.p,{children:"Now you can start writing TypeScript theme components."}),"\n",(0,r.jsx)(n.h2,{id:"typing-config",children:"Typing the config file"}),"\n",(0,r.jsx)(n.p,{children:"It is possible to use a TypeScript config file in Docusaurus."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",metastring:'title="docusaurus.config.ts"',children:"import type {Config} from '@docusaurus/types';\nimport type * as Preset from '@docusaurus/preset-classic';\n\n// highlight-next-line\nconst config: Config = {\n title: 'My Site',\n favicon: 'img/favicon.ico',\n\n /* Your site config here */\n\n presets: [\n [\n 'classic',\n {\n /* Your preset config here */\n // highlight-next-line\n } satisfies Preset.Options,\n ],\n ],\n\n themeConfig: {\n /* Your theme config here */\n // highlight-next-line\n } satisfies Preset.ThemeConfig,\n};\n\nexport default config;\n"})}),"\n",(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:["It is also possible to use ",(0,r.jsx)(n.a,{href:"https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html",children:"JSDoc type annotations"})," within a ",(0,r.jsx)(n.code,{children:".js"})," file:"]}),(0,r.jsx)(n.p,{children:"By default, the Docusaurus TypeScript config does not type-check JavaScript files."}),(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"// @ts-check"})," comment ensures the config file is properly type-checked when running ",(0,r.jsx)(n.code,{children:"npx tsc"}),"."]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config.js"',children:"// highlight-next-line\n// @ts-check\n\n// highlight-next-line\n/** @type {import('@docusaurus/types').Config} */\nconst config = {\n tagline: 'Dinosaurs are cool',\n favicon: 'img/favicon.ico',\n\n /* Your site config here */\n\n presets: [\n [\n '@docusaurus/preset-classic',\n // highlight-next-line\n /** @type {import('@docusaurus/preset-classic').Options} */\n (\n {\n /* Your preset config here */\n }\n ),\n ],\n ],\n themeConfig:\n // highlight-next-line\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n (\n {\n /* Your theme config here */\n }\n ),\n};\n\nexport default config;\n"})})]}),"\n",(0,r.jsxs)(n.admonition,{type:"tip",children:[(0,r.jsx)(n.p,{children:"Type annotations are very useful and help your IDE understand the type of config objects!"}),(0,r.jsx)(n.p,{children:"The best IDEs (VS Code, WebStorm, IntelliJ...) will provide a nice auto-completion experience."})]}),"\n",(0,r.jsx)(n.h2,{id:"swizzling-typescript-theme-components",children:"Swizzling TypeScript theme components"}),"\n",(0,r.jsxs)(n.p,{children:["For themes that support TypeScript theme components, you can add the ",(0,r.jsx)(n.code,{children:"--typescript"})," flag to the end of the ",(0,r.jsx)(n.code,{children:"swizzle"})," command to get TypeScript source code. For example, the following command will generate ",(0,r.jsx)(n.code,{children:"index.tsx"})," and ",(0,r.jsx)(n.code,{children:"styles.module.css"})," into ",(0,r.jsx)(n.code,{children:"src/theme/Footer"}),"."]}),"\n",(0,r.jsxs)(o.Z,{groupId:"npm2yarn",children:[(0,r.jsx)(c.Z,{value:"npm",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run swizzle @docusaurus/theme-classic Footer -- --typescript\n"})})}),(0,r.jsx)(c.Z,{value:"yarn",label:"Yarn",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"yarn swizzle @docusaurus/theme-classic Footer --typescript\n"})})}),(0,r.jsx)(c.Z,{value:"pnpm",label:"pnpm",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle @docusaurus/theme-classic Footer --typescript\n"})})}),(0,r.jsx)(c.Z,{value:"bun",label:"Bun",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"bun run swizzle @docusaurus/theme-classic Footer --typescript\n"})})})]}),"\n",(0,r.jsxs)(n.p,{children:["All official Docusaurus themes support TypeScript theme components, including ",(0,r.jsx)(n.a,{href:"/docs/api/themes/@docusaurus/theme-classic",children:(0,r.jsx)(n.code,{children:"theme-classic"})}),", ",(0,r.jsx)(n.a,{href:"/docs/api/themes/@docusaurus/theme-live-codeblock",children:(0,r.jsx)(n.code,{children:"theme-live-codeblock"})}),", and ",(0,r.jsx)(n.a,{href:"/docs/api/themes/@docusaurus/theme-search-algolia",children:(0,r.jsx)(n.code,{children:"theme-search-algolia"})}),". If you are a Docusaurus theme package author who wants to add TypeScript support, see the ",(0,r.jsx)(n.a,{href:"/docs/api/plugin-methods/extend-infrastructure#getTypeScriptThemePath",children:"Lifecycle APIs docs"}),"."]})]})}function h(e={}){let{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},58636:function(e,n,t){t.d(n,{Z:()=>i});var s=t(85893);t(67294);var r=t(90496);function i(e){let{children:n,hidden:t,className:i}=e;return(0,s.jsx)("div",{role:"tabpanel",className:(0,r.Z)("tabItem_pnkT",i),hidden:t,children:n})}},15398:function(e,n,t){t.d(n,{Z:()=>x});var s=t(85893),r=t(67294),i=t(90496),o=t(54947),c=t(3620),a=t(844),l=t(97486),u=t(32263),p=t(16971);function d(e){return r.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||r.isValidElement(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function h(e){let{value:n,tabValues:t}=e;return t.some(e=>e.value===n)}var m=t(71607);function f(e){let{className:n,block:t,selectedValue:r,selectValue:c,tabValues:a}=e,l=[],{blockElementScrollPositionUntilNextRender:u}=(0,o.o5)(),p=e=>{let n=e.currentTarget,t=a[l.indexOf(n)].value;t!==r&&(u(n),c(t))},d=e=>{let n=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{let t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{let t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1]}}n?.focus()};return(0,s.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":t},n),children:a.map(e=>{let{value:n,label:t,attributes:o}=e;return(0,s.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>{l.push(e)},onKeyDown:d,onClick:p,...o,className:(0,i.Z)("tabs__item","tabItem_AQgk",o?.className,{"tabs__item--active":r===n}),children:t??n},n)})})}function g(e){let{lazy:n,children:t,selectedValue:o}=e,c=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){let e=c.find(e=>e.props.value===o);return e?(0,r.cloneElement)(e,{className:(0,i.Z)("margin-top--md",e.props.className)}):null}return(0,s.jsx)("div",{className:"margin-top--md",children:c.map((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==o}))})}function y(e){let n=function(e){let{defaultValue:n,queryString:t=!1,groupId:s}=e,i=function(e){let{values:n,children:t}=e;return(0,r.useMemo)(()=>{let e=n??d(t).map(e=>{let{props:{value:n,label:t,attributes:s,default:r}}=e;return{value:n,label:t,attributes:s,default:r}});return!function(e){let n=(0,u.lx)(e,(e,n)=>e.value===n.value);if(n.length>0)throw Error(`Docusaurus error: Duplicate values "${n.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e},[n,t])}(e),[o,m]=(0,r.useState)(()=>(function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:t}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}let s=t.find(e=>e.default)??t[0];if(!s)throw Error("Unexpected error: 0 tabValues");return s.value})({defaultValue:n,tabValues:i})),[f,g]=function(e){let{queryString:n=!1,groupId:t}=e,s=(0,c.k6)(),i=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,l._X)(i),(0,r.useCallback)(e=>{if(!i)return;let n=new URLSearchParams(s.location.search);n.set(i,e),s.replace({...s.location,search:n.toString()})},[i,s])]}({queryString:t,groupId:s}),[y,x]=function(e){let{groupId:n}=e,t=n?`docusaurus.tab.${n}`:null,[s,i]=(0,p.Nk)(t);return[s,(0,r.useCallback)(e=>{t&&i.set(e)},[t,i])]}({groupId:s}),j=(()=>{let e=f??y;return h({value:e,tabValues:i})?e:null})();return(0,a.Z)(()=>{j&&m(j)},[j]),{selectedValue:o,selectValue:(0,r.useCallback)(e=>{if(!h({value:e,tabValues:i}))throw Error(`Can't select invalid tab value=${e}`);m(e),g(e),x(e)},[g,x,i]),tabValues:i}}(e);return(0,s.jsxs)("div",{className:(0,i.Z)("tabs-container","tabList_Qoir"),children:[(0,s.jsx)(f,{...n,...e}),(0,s.jsx)(g,{...n,...e})]})}function x(e){let n=(0,m.Z)();return(0,s.jsx)(y,{...e,children:d(e.children)},String(n))}},80980:function(e,n,t){t.d(n,{Z:()=>c,a:()=>o});var s=t(67294);let r={},i=s.createContext(r);function o(e){let n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]);