vuejs / vitepress

Vite & Vue powered static site generator.
https://vitepress.dev
MIT License
12.93k stars 2.09k forks source link

Markdown-it plugin type issue #3935

Closed xsjcTony closed 4 months ago

xsjcTony commented 4 months ago

Describe the bug

I'm encountering the type issue of markdown-it when using the markdown.config property in the vitepress config file. I have 3 plugins, all with issues. I reproduced the simplest one in the reproduction below. I believe they have the same problem. I'll log all the issues I'm having in Additional Context field, but please have a look at the reproduction below, thanks.

Reproduction

https://stackblitz.com/edit/vite-qvbnhu?file=docs%2F.vitepress%2Fconfig.ts

Expected behavior

No error is raised.

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
    Memory: 7.04 GB / 31.69 GB
  Binaries:
    Node: 20.11.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.2.4 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.1.4 - ~\AppData\Local\pnpm\pnpm.EXE
  Browsers:
    Edge: Chromium (123.0.2420.97)
    Internet Explorer: 11.0.22621.3527
  npmPackages:
    vitepress: ^1.2.2 => 1.2.2

Additional context

PS C:\Dev\docs> npm run build

> build
> vue-tsc && vitepress build

.vitepress/config.ts:113:14 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(plugin: PluginSimple): MarkdownIt', gave the following error.
    Argument of type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs").PluginSimple' is not assignable to parameter of type 'PluginSimple'.
      Types of parameters 'md' and 'md' are incompatible.
        Type 'MarkdownIt' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs")'.
          The types returned by 'inline.ruler.getRules(...)' are incompatible between these types.
            Type 'RuleInline[]' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs").ParserInline.RuleInline[]'.
              Type 'RuleInline' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs").ParserInline.RuleInline'.
                Types of parameters 'state' and 'state' are incompatible.
                  Type 'StateInline' is not assignable to type 'StateInline'. Two different types with this name exist, but they are unrelated.
                    The types of 'md.utils.lib.mdurl' are incompatible between these types.
                      Property 'Url' is missing in type '{ decode: { (str: string, exclude?: string | undefined): string; defaultChars: string; componentChars: string; }; encode: { (str: string, exclude?: string | undefined, keepEscaped?: boolean | undefined): string; defaultChars: string; componentChars: string; }; format(url: Omit<...>): string; parse(url: string | Url,...' but required in type 'typeof mdurl'.
  Overload 2 of 3, '(plugin: PluginWithOptions<any>, options?: any): MarkdownIt', gave the following error.
    Argument of type 'PluginSimple' is not assignable to parameter of type 'PluginWithOptions<any>'.
      Types of parameters 'md' and 'md' are incompatible.
        Type 'MarkdownIt' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs")'.
  Overload 3 of 3, '(plugin: PluginWithParams, ...params: any[]): MarkdownIt', gave the following error.
    Argument of type 'PluginSimple' is not assignable to parameter of type 'PluginWithParams'.
      Types of parameters 'md' and 'md' are incompatible.
        Type 'MarkdownIt' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs")'.

113       md.use(containerPlugin)
                 ~~~~~~~~~~~~~~~

  node_modules/vitepress/dist/node/index.d.ts:393:12
    393   export { mdurl_Url as Url, mdurl_decode as decode, mdurl_encode as encode, mdurl_format as format, mdurl_parse as parse };
                   ~~~~~~~~~~~~~~~~
    'Url' is declared here.

.vitepress/config.ts:114:14 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(plugin: PluginSimple): MarkdownIt', gave the following error.
    Argument of type '(md: MarkdownIt) => void' is not assignable to parameter of type 'PluginSimple'.
      Types of parameters 'md' and 'md' are incompatible.
        Type 'MarkdownIt' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs")'.
  Overload 2 of 3, '(plugin: PluginWithOptions<any>, options?: any): MarkdownIt', gave the following error.
    Argument of type '(md: MarkdownIt) => void' is not assignable to parameter of type 'PluginWithOptions<any>'.
      Types of parameters 'md' and 'md' are incompatible.
        Type 'MarkdownIt' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs")'.
  Overload 3 of 3, '(plugin: PluginWithParams, ...params: any[]): MarkdownIt', gave the following error.
    Argument of type '(md: MarkdownIt) => void' is not assignable to parameter of type 'PluginWithParams'.
      Types of parameters 'md' and 'md' are incompatible.
        Type 'MarkdownIt' is not assignable to type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs")'.

114         .use(externalLinkIconPlugin)
                 ~~~~~~~~~~~~~~~~~~~~~~

.vitepress/config.ts:115:14 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(plugin: PluginSimple): MarkdownIt', gave the following error.
    Argument of type 'import("C:/Dev/nf-docs/node_modules/@types/markdown-it/dist/index.cjs").PluginSimple' is not assignable to parameter of type 'PluginSimple'.
  Overload 2 of 3, '(plugin: PluginWithOptions<any>, options?: any): MarkdownIt', gave the following error.
    Argument of type 'PluginSimple' is not assignable to parameter of type 'PluginWithOptions<any>'.
  Overload 3 of 3, '(plugin: PluginWithParams, ...params: any[]): MarkdownIt', gave the following error.
    Argument of type 'PluginSimple' is not assignable to parameter of type 'PluginWithParams'.

115         .use(requestBlockPlugin);
                 ~~~~~~~~~~~~~~~~~~

Found 3 errors in the same file, starting at: .vitepress/config.ts:113

Validations

brc-dd commented 4 months ago

Fixed the issue here, but your plugin types are wrong too. They are for markdown-it v13. You need to change imports:

import type { RenderRule } from 'markdown-it/lib/renderer.mjs';

...

const renderToken: RenderRule = ...

upstream issue - https://github.com/Swatinem/rollup-plugin-dts/issues/311

xsjcTony commented 4 months ago

Sorry I'm not familiar with markdown-it, so you mean @types/markdown-it contains both types for v13 and v14 and I'm using the v13 part?🤣

brc-dd commented 4 months ago

No. That part is also throwing error in the stackblitz example you've provided. I'm just suggesting how to fix errors inside that plugins/externalLinkIcon.ts file

PS: you don't need a plugin for external link icon, it's now builtin https://vitepress.dev/reference/default-theme-config#externallinkicon

xsjcTony commented 4 months ago

That's a bit confusing, because I installed the v14 of @types/markdown-it, hence I'm assuming below are the same, as they are just different way to import the same thing.

import type { Renderer } from 'markdown-it';
type RenderRule = Renderer.RenderRule;
import type { RenderRule } from 'markdown-it/lib/renderer.mjs';

PS: yeah I'm aware there's a built-in one, but I just want to use my own icon there.

xsjcTony commented 4 months ago

And I believe I need to fix below as per your suggestion as well, even I don't understand why is that🤦‍♀️ From

import type { ParserBlock } from 'markdown-it';
type RuleBlock = ParserBlock.RuleBlock;

To

import type { RuleBlock } from 'markdown-it/lib/parser_block.mjs';

I believe PluginSimple remains the same like this?

import type { PluginSimple } from 'markdown-it';
brc-dd commented 4 months ago

hence I'm assuming below are the same, as they are just different way to import the same thing.

no

there is no Renderer type exported from markdown-it's default entrypoint.

I believe PluginSimple remains the same like this?

yeah

You can just type and check. If it doesn't show errors like this, then it's okay:

Module '"markdown-it"' has no exported member 'Renderer'. Did you mean to use 'import Renderer from "markdown-it"' instead? ts(2614)
xsjcTony commented 4 months ago

I see. However my IDE can pick it up and seems vue-tsc can as well. image image But I agree with you, the CJS build of @types/markdown-it is a mess. If I use the ESM dts file, it's very clear which one I should import, but it's confusing that CJS build is exporting things differently from the ESM build🤣 image

Thanks for the suggestions overall, I've fixed those.

xsjcTony commented 4 months ago

Indeed it's confusing, wondering if there's a way I can default it to import from ESM dts file instead of CJS, without having to add .mjs after the filename

brc-dd commented 4 months ago

I see. However my IDE can pick it up and seems vue-tsc can as well.

Ah, sorry. I was getting those errors because I changed moduleResolution to nodenext in your example's tsconfig. Right, with moduleResolution node it will resolve to CJS export and it will not throw any error on import type { Renderer } from 'markdown-it'

Indeed it's confusing, wondering if there's a way I can default it to import from ESM dts file instead of CJS, without having to add .mjs after the filename

You can try setting your moduleResolution to bundler.

xsjcTony commented 4 months ago

Yes, I've tried it as it works both ways with the new fix.

You can try setting your moduleResolution to bundler.

Yeah that works. Thanks for the suggestion!

xsjcTony commented 4 months ago

Also thanks for the quick fix💖 Appreciate that.