TypeScript
使用 TypeScript Twoslash 在您的代码块中包含 TypeScript 编译器的信息。
content.md
```tsconst hi = "Hello"const msg = `${hi}, world`// ^?// @errors: 2588msg = 123```
const = "Hello"const = `${}, world`const msg: "Hello, world"= 123Cannot assign to 'msg' because it is a constant.
Implementation
我们使用 twoslash 库从代码块中提取 TypeScript 编译器的信息。更多信息请查看 twoslash 文档。
npm i twoslash
在 Code 组件中,我们运行 TypeScript 并将 twoslash 查询和悬停转换为 Code Hike 注释,然后使用类似于标注和工具提示的处理器。
code.tsx
import { RawCode, Pre, highlight, AnnotationHandler } from "codehike/code"import { createTwoslasher } from "twoslash"const twoslasher = createTwoslasher({fsMap: new Map(),compilerOptions: {},})async function Code({ codeblock }: { codeblock: RawCode }) {// 运行 TypeScript:const { hovers, code, queries, errors } = twoslasher(codeblock.value,codeblock.lang,)// 高亮代码:const highlighted = await highlight({ ...codeblock, value: code },"github-dark",)hovers.forEach(({ text, line, character, length }) => {highlighted.annotations.push({name: "tooltip",query: text,lineNumber: line + 1,fromColumn: character + 1,toColumn: character + length,})})queries.forEach(({ text, line, character }) => {highlighted.annotations.push({name: "callout",query: text,fromLineNumber: line + 1,toLineNumber: line + 1,data: { character },})})errors.forEach(({ text, line, character }) => {highlighted.annotations.push({name: "callout",query: text,fromLineNumber: line + 1,toLineNumber: line + 1,data: { character, className: "text-red-400" },})})return (<PreclassName=""code={highlighted}handlers={[tooltip, callout]}/>)}import {TooltipProvider,Tooltip,TooltipTrigger,TooltipContent,TooltipArrow,} from "@/components/ui/tooltip"const tooltip: AnnotationHandler = {name: "tooltip",Inline: async ({ children, annotation }) => {const { query, data } = annotationconst highlighted = await highlight({ value: query, lang: "ts", meta: "" },"github-dark",)return (<TooltipProvider delayDuration={300}><Tooltip><TooltipTrigger className="">{children}</TooltipTrigger><TooltipContent className="" sideOffset={0}><Pre code={highlighted} className="" /><TooltipArrow className="" /></TooltipContent></Tooltip></TooltipProvider>)},}const callout: AnnotationHandler = {name: "callout",Block: ({ annotation, children }) => {const { character, className } = annotation.datareturn (<>{children}<divstyle={{ minWidth: `${character + 4}ch` }}className={"w-fit border bg-zinc-900 border-current rounded px-2 relative -ml-[1ch] mt-1 whitespace-break-spaces" +" " +className}><divstyle={{ left: `${character + 1}ch` }}className=""/>{annotation.query}</div></>)},}