twoslashes/twoslash

Cannot render code with errors

nostrorom opened this issue · 5 comments

Hello,

When trying twoslah with shiki, compiler errors are treated as real errors instead of being rendered to html

Code without errors

index.js

import { codeToHtml } from 'shiki';
import { transformerTwoslash } from '@shikijs/twoslash';

const html = await codeToHtml(`console.log()`, {
  lang: 'ts',
  theme: 'vitesse-dark',
  transformers: [
    transformerTwoslash()
  ],
});

console.log(html);

then
node ./index.js

correctly renders

<pre class="shiki vitesse-dark twoslash lsp" style="background-color:#121212;color:#dbd7caee" tabindex="0"><code><span class="line"><span style="color:#DBD7CAEE"><span class="twoslash-hover"><span class="twoslash-popup-container"><code class="twoslash-popup-code"><span class="line"><span style="color:#CB7676">var </span><span style="color:#BD976A">console</span><span style="color:#666666">: </span><span style="color:#5DA994">Console</span></span></code></span>console</span></span><span style="color:#DBD7CAEE">.</span><span style="color:#DBD7CAEE"><span class="twoslash-hover"><span class="twoslash-popup-container"><code class="twoslash-popup-code"><span class="line"><span style="color:#BD976A">Console</span><span style="color:#666666">.</span><span style="color:#80A665">log</span><span style="color:#666666">(...</span><span style="color:#BD976A">data</span><span style="color:#DBD7CAEE">: </span><span style="color:#BD976A">any</span><span style="color:#666666">[])</span><span style="color:#DBD7CAEE">: </span><span style="color:#CB7676">void</span></span></code><div class="twoslash-popup-docs">[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log)</div></span>log</span></span><span style="color:#DBD7CAEE">()</span></span></code></pre>

Code without errors

index.js

import { codeToHtml } from 'shiki';
import { transformerTwoslash } from '@shikijs/twoslash';

const html = await codeToHtml(`console.loog()`, {
  lang: 'ts',
  theme: 'vitesse-dark',
  transformers: [
    transformerTwoslash()
  ],
});

console.log(html);

then
node ./index.js

throws an error instead of rendering:

  title: 'Errors were thrown in the sample, but not included in an error tag',
  description: 'These errors were not marked as being expected: 2551. \n' +
    'Expected: // @errors: 2551',
  recommendation: 'Compiler Errors:\n' +
    '\n' +
    'index.ts\n' +
    "  [2551] 8 - Property 'loog' does not exist on type 'Console'. Did you mean 'log'?",
  code: undefined

Using error tags to suppress errors

Following the expected tag leads to other errors, also suppressing them

These errors were not marked as being expected: 2551 1146 1005. 
Expected: // @errors: 2551 1146 1005

index.js

import { codeToHtml } from 'shiki';
import { transformerTwoslash } from '@shikijs/twoslash';

const html = await codeToHtml(` // @errors: 2551 1146 1005 console.loog()`, {
  lang: 'ts',
  theme: 'vitesse-dark',
  transformers: [
    transformerTwoslash()
  ],
});

console.log(html);

then
node ./index.js

this renders the HTML, but the errors are also suppressed here, defeating the purpose

<pre class="shiki vitesse-dark twoslash lsp" style="background-color:#121212;color:#dbd7caee" tabindex="0"><code><span class="line"><span style="color:#758575DD">// @errors:2551 1146 1005 console.loog()</span></span></code></pre>

What am I missing here ?

What are you trying to do? Are you trying to render all errors, or ignores all errors?

You can add // @noErrors or // @noErrorVaildation deps on your need:

export interface HandbookOptions {
/**
* An array of TS error codes, which you write as space separated - this is so the tool can know about unexpected errors
*/
errors: number[]
/**
* Suppress errors for diagnostics and display
*
* Setting true to suppress all errors, or an array of error codes to suppress
*/
noErrors: boolean | number[]
/**
* Declare that you don't need to validate that errors have corresponding annotations, defaults to false
*/
noErrorValidation: boolean
/**
* Whether to disable the pre-cache of LSP calls for interesting identifiers, defaults to false
*/
noStaticSemanticInfo: boolean
/**
* Shows the JS equivalent of the TypeScript code instead
*/
showEmit: boolean
/**
* Must be used with showEmit, lets you choose the file to present instead of the source - defaults to index.js which
* means when you just use `showEmit` above it shows the transpiled JS.
*/
showEmittedFile?: string
/**
* Do not remove twoslash notations from output code, the nodes will have the position of the input code.
* @default false
*/
keepNotations: boolean
/**
* Do not check errors in the cutted code.
* @default false
*/
noErrorsCutted: boolean
}

Hi @antfu

Thanks for your quick answer; reading it has made me understand I had the wrong expectations.

What I was trying to do was have this kind of error line:

image

<div class="twoslash-meta-line twoslash-error-line">Type 'string' is not assignable to type 'number'.</div><div class="twoslash-meta-line twoslash-error-line">Type 'number' is not assignable to type 'string'.</div>

Which I can reproduce from the example in the docs; my mistake was expecting similar error line divs also for JS errors.
I know realise this is not the scope of twoslash, only TS errors.

Though if there is a way to also generate something like this for the error in my OP, I'd be happy to kown 😄

<div class="twoslash-meta-line twoslash-error-line">
  Property 'loog' does not exist on type 'Console'. Did you mean 'log'?"
</div>

Otherwise the issue is closed for me

Idk, maybe try adding // @ts-check to your js file?

Did no seem to work. I'm still fiddling with things to see if I can probably describe the cases where I find there is expected/unexpected behaviour, and then provide reproductible examples. Is there a discussion page where I can take this conversation to instead of issues? I'll close this for now.

Anyway thank you guys for yout work on this project, it's an awesome tool 👍