Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Extend Native Macros in ts-macros for Safer Type Inference and Compile-Time Transformations #92

Open
rubeniskov opened this issue Oct 15, 2024 · 0 comments

Comments

@rubeniskov
Copy link

Is your feature request related to a problem? Please describe.

I would like to extend the native macros in ts-macros to provide more complex macros that can infer types and produce outputs at compile time. Currently, the $$raw macro allows for low-level AST manipulations but can be harmful as it has system-level access, which is a concern for security and stability. I want to create macros that are sensitive to certain configurations, like noComptime, to restrict unsafe operations while still enabling powerful type inference and compile-time tooling.

For example, I would like to create a macro such as $$pick(props), which extracts properties from an argument based on a given type at compile time. This would be especially useful when working with React to deconstruct props and streamline prop drilling across components.

Describe the solution you'd like

I propose extending the ts-macros transformer with a configurable system for defining new macros at a lower level, ensuring that these macros respect specific configurations such as noComptime. This would allow developers to create powerful, type-inferable macros that perform compile-time transformations while restricting dangerous or unwanted operations like those enabled by $$raw.

This can be achieved with the exposure of the nativeMacros map and allowing a new argument in the MacroTransformer liek this

import nativeMacros, { NativeMacro } from 'ts-macros/dist/nativeMacros';
import { Macro, MacroTransformer } from 'ts-macros/dist/transformer';
import * as ts from 'typescript';

export const macros = new Map<ts.Symbol, Macro>([]);

const customNativeMacros: Record<string, NativeMacro> = {
  ...nativeMacros,
  $$pick: {
    call(args, transformer, callSite) {
      // The logic of the macro
    },
  },
};

export interface TsMacrosConfig {
  noComptime?: boolean;
  watchMode?: boolean;
  keepImports?: boolean;
  logFileData?: boolean;
  // Custom options
}

const transformer =
  (program: ts.Program, config?: TsMacrosConfig): ts.TransformerFactory<ts.Node> =>
  (ctx) => {
    const typeChecker = program.getTypeChecker();
    const transformer = new MacroTransformer(ctx, typeChecker, macros, customNativeMacros, {
      ...config,
      noComptime: config?.noComptime ?? false,
    });
    return (firstNode) => {
      return transformer.run(firstNode as ts.SourceFile);
    };
  };

export default transformer;

Additional context

This feature would allow developers to create safer, more powerful macros that enhance TypeScript’s compile-time capabilities while avoiding the potential risks of $$raw. It would also facilitate macros tailored for specific use cases, such as React component prop management, enabling clean, type-safe code.

This feature request outlines the need for safer, configurable macros with type inference capabilities while emphasizing security considerations when extending native macros like $$raw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant