TIL: Using Twoslash with Shiki and Astro
| View comments on Hacker NewsDo you want code snippets like below on your Astro site?
Note: you can hover over types to see their definitions.
function function createLabel<T extends number | string>(idOrName: T): NameOrId<T>createLabel<function (type parameter) T in createLabel<T extends number | string>(idOrName: T): NameOrId<T>T extends number | string>(idOrName: T extends number | stringidOrName: function (type parameter) T in createLabel<T extends number | string>(idOrName: T): NameOrId<T>T): type NameOrId<T extends number | string> = T extends number ? IdLabel : NameLabelNameOrId<function (type parameter) T in createLabel<T extends number | string>(idOrName: T): NameOrId<T>T> {
  throw "unimplemented";
}
let let a: NameLabela = function createLabel<"typescript">(idOrName: "typescript"): NameLabelcreateLabel("typescript");
It’s super easy. In your astro.config.ts file, add the following:
import { function rendererRich(options?: RendererRichOptions): TwoslashRendererAn alternative renderer that providers better prefixed class names,
with syntax highlight for the info text.rendererRich, function transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformerFactory function to create a Shiki transformer for twoslash integrations.transformerTwoslash } from "@shikijs/twoslash";
export default function defineConfig(config: AstroUserConfig): AstroUserConfigSee the full Astro Configuration API Documentation
https://astro.build/configdefineConfig({
  AstroUserConfig.markdown?: {
    shikiConfig?: Partial<ShikiConfig>;
    syntaxHighlight?: "shiki" | "prism" | false;
    remarkPlugins?: RemarkPlugins;
    rehypePlugins?: RehypePlugins;
    gfm?: boolean;
    smartypants?: boolean;
    remarkRehype?: RemarkRehype;
} | undefined
shikiConfig?: Partial<ShikiConfig> | undefinedshikiConfig: {
      transformers?: ShikiTransformer[] | undefinedtransformers: [
        function transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformerFactory function to create a Shiki transformer for twoslash integrations.transformerTwoslash({
          TransformerTwoslashOptions.renderer?: TwoslashRenderer | undefinedCustom renderers to decide how each info should be renderedrenderer: function rendererRich(options?: RendererRichOptions): TwoslashRendererAn alternative renderer that providers better prefixed class names,
with syntax highlight for the info text.rendererRich(),
        }),
      ],
    },
  },
});
Import this CSS in your layout:
import "@shikijs/twoslash/style-rich.css";
Add the following CSS and import it in your layout:
// fixes an issue where type popups are cut off
.astro-code {
  overflow: visible !important;
}
Bonus: enable an automatic light & dark mode. Add the following CSS from Shiki’s documentation:
@media (prefers-color-scheme: dark) {
  .shiki,
  .shiki span {
    color: var(--shiki-dark) !important;
    background-color: var(--shiki-dark-bg) !important;
    /* Optional, if you also want font styles */
    font-style: var(--shiki-dark-font-style) !important;
    font-weight: var(--shiki-dark-font-weight) !important;
    text-decoration: var(--shiki-dark-text-decoration) !important;
  }
}
Add the following to your astro.config.ts:
export default function defineConfig(config: AstroUserConfig): AstroUserConfigSee the full Astro Configuration API Documentation
https://astro.build/configdefineConfig({
  AstroUserConfig.markdown?: {
    shikiConfig?: Partial<ShikiConfig>;
    syntaxHighlight?: "shiki" | "prism" | false;
    remarkPlugins?: RemarkPlugins;
    rehypePlugins?: RehypePlugins;
    gfm?: boolean;
    smartypants?: boolean;
    remarkRehype?: RemarkRehype;
} | undefined
shikiConfig?: Partial<ShikiConfig> | undefinedshikiConfig: {
      theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw | undefinedtheme: "github-dark",
      themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw> | undefinedthemes: {
        light: "github-light"light: "github-light",
        dark: "github-dark"dark: "github-dark",
      },
    },
  },
});
You can try it on this site by toggling your browser’s or operating system’s dark mode.
Check out Shiki’s Twoslash documentation for details.