Skip to content

ts-macro/ts-macro

Repository files navigation

TS Macro

NPM version

This is a VSCode plugin for define TS(X) macro powered by Volar.js.

Usage

  1. Install VSCode Plugin

  2. Create tsm.config.ts at the same level of tsconfig.json .

  3. Writing your first plugin.

    // tsm.config.ts
    export default {
      plugins: [
        {
          name: 'ts-macro-define-style',
          resolveVirtualCode({ codes }) {
            // declare the `defineStyle` function type for every TS(X) files.
            codes.push('declare function defineStyle<T>(style: string): T ')
          },
        },
      ],
    }

    Or You can use createPlugin to define plugin.

    // tsm.config.ts
    import { createPlugin, replaceRange } from 'ts-macro'
    
    const defineStylePlugin = createPlugin<{ macro: string }>(
      ({ ts, compilerOptions }, userOptions) => {
        return {
          name: 'ts-macro-define-style',
          resolveVirtualCode({ ast, codes }) {
            codes.push(
              `declare function ${userOptions.macro}<T>(style: string): T `,
            )
    
            ts.forEachChild(ast, walk)
    
            function walk(
              node: import('typescript').Node,
              parent: import('typescript').Node,
            ) {
              if (
                ts.isCallExpression(node) &&
                node.expression.getText(ast).startsWith(userOptions.macro)
              ) {
                // Add generic type for defineStyle.
                replaceRange(
                  codes,
                  node.arguments.pos - 1,
                  node.arguments.pos - 1,
                  '<{ foo: string }>',
                )
              }
    
              ts.forEachChild(node, (child) => {
                walk(child, node)
              })
            }
          },
        }
      },
    )
    
    export default {
      plugins: [
        defineStylePlugin({
          macro: 'defineStyle',
        }),
      ],
    }
  4. Result

    image

Example

https://github.com/ts-macro/ts-macro/blob/main/playground

TSC

Use tsmc instead of tsc to compile TS.

Install

pnpm add @ts-macro/tsc -D

Usage in package.json.

{
  "scripts": {
    "typecheck": "tsmc --onEmit"
  }
}

References

Thanks for these great projects, I have learned a lot from them.