shikijs / shiki

A beautiful yet powerful syntax highlighter
http://shiki.style/
MIT License
9.91k stars 361 forks source link

Shiki types are broken on non-DOM projects, again... #665

Closed Gerrit0 closed 5 months ago

Gerrit0 commented 5 months ago

Validations

Describe the bug

I've fixed this before, but with the 1.0 rework apparently these changes were reverted. https://github.com/shikijs/shiki/pull/402.

TypeDoc is a Node-only project which does not have "lib": ["DOM"] in its tsconfig. When attempting to use newer versions of Shiki, compiling has type errors due to referencing types which do not exist.

Shiki should either provide a separate import for the browser bundle which includes these type references, or forward declare the interface which Shiki requires as I did previously

My recommendation for fixing this would be to split the Shiki monorepo so that each published package has its own tsconfig, which is referenced with TypeScript's packages feature. Then, remove "DOM" from the root tsconfig in the repo, and only include it in the docs/.vitepress, packages/monaco, and packages/vitepress-twoslash projects.

node_modules/@shikijs/core/dist/chunk-index.d.mts:2:50 - error TS2503: Cannot find namespace 'WebAssembly'.

2     (importObject: Record<string, Record<string, WebAssembly.ImportValue>> | undefined): Promise<WebAssemblyInstance>;
                                                   ~~~~~~~~~~~

node_modules/@shikijs/core/dist/chunk-index.d.mts:4:28 - error TS2503: Cannot find namespace 'WebAssembly'.

4 type WebAssemblyInstance = WebAssembly.WebAssemblyInstantiatedSource | WebAssembly.Instance | WebAssembly.Instance['exports'];
                             ~~~~~~~~~~~

node_modules/@shikijs/core/dist/chunk-index.d.mts:4:72 - error TS2503: Cannot find namespace 'WebAssembly'.

4 type WebAssemblyInstance = WebAssembly.WebAssemblyInstantiatedSource | WebAssembly.Instance | WebAssembly.Instance['exports'];
                                                                         ~~~~~~~~~~~

node_modules/@shikijs/core/dist/chunk-index.d.mts:4:95 - error TS2503: Cannot find namespace 'WebAssembly'.

4 type WebAssemblyInstance = WebAssembly.WebAssemblyInstantiatedSource | WebAssembly.Instance | WebAssembly.Instance['exports'];
                                                                                                ~~~~~~~~~~~

node_modules/@shikijs/core/dist/chunk-index.d.mts:10:43 - error TS2304: Cannot find name 'Response'.

10     data: ArrayBufferView | ArrayBuffer | Response;
                                             ~~~~~~~~

node_modules/@shikijs/core/dist/chunk-index.d.mts:13:110 - error TS2304: Cannot find name 'Response'.

13 type LoadWasmOptionsPlain = OnigurumaLoadOptions | WebAssemblyInstantiator | ArrayBufferView | ArrayBuffer | Response;
                                                                                                                ~~~~~~~~

Reproduction

see above

Contributes

Gerrit0 commented 5 months ago

Also, the issue template-form thing is broken, it gives you only one line to enter a reproduction, which is completely unusable if you want to post a couple tiny files.

antfu commented 5 months ago

This is only type-level. I'd suggest you disable the lib check via skipLibCheck: true or do the type shims locally - I don't think there is a workaround to fix this on our side. Vendoring those types is not a long-term solution and will potentially create misalignment that might affect more users.

Gerrit0 commented 5 months ago

Libraries dictating compiler options is not a good thing. (with the possible exception of strictNullChecks)

It'd be really nice to not have to mess with types when installing Shiki, I tried experimenting with some declaration merging to add the types, but unfortunately the WebAssembly types are incredibly unfriendly to declaration merging with, so they literally can't be vendored in Shiki because of loadWasm.

I guess I'll declaration merge in some types that'll totally break in DOM projects, but works for my use case... ick.

Gerrit0 commented 5 months ago

In case someone else runs into this, what I added to TypeDoc is:

// Shiki 1.x declares a `loadWasm` function which takes these types as input.
// They are declared in the DOM library, but since TypeDoc doesn't use that library,
// we have to declare some shims, intentionally crafted to not be accidentally
// constructed.

declare namespace WebAssembly {
    interface Instance {
        __shikiHack: never;
        exports: unknown;
    }
    interface WebAssemblyInstantiatedSource {
        __shikiHack: never;
    }
    type ImportValue = unknown;
}

interface Response {
    __shikiHack: never;
}