davidbonnet / astring

🌳 Tiny and fast JavaScript code generator from an ESTree-compliant AST.
MIT License
1.17k stars 57 forks source link

Widen types for custom generator #709

Open paoloricciuti opened 4 months ago

paoloricciuti commented 4 months ago

Motivation

Currently the types for the custom generator looks like this

/**
 * Code generator for each node type.
 */
export type Generator = {
  [T in EstreeNode['type']]: (
    node: EstreeNode & { type: T },
    state: State,
  ) => void
}

/**
 * Code generator options.
 */
export interface Options<Output = null> {
  /**
   * If present, source mappings will be written to the generator.
   */
  sourceMap?: SourceMapGenerator
  /**
   * String to use for indentation, defaults to `"␣␣"`.
   */
  indent?: string
  /**
   * String to use for line endings, defaults to `"\n"`.
   */
  lineEnd?: string
  /**
   * Indent level to start from, defaults to `0`.
   */
  startingIndentLevel?: number
  /**
   * Generate comments if `true`, defaults to `false`.
   */
  comments?: boolean
  /**
   * Output stream to write the render code to, defaults to `null`.
   */
  output?: Output
  /**
   * Custom code generator logic.
   */
  generator?: Generator
}

which is fine but this means we have no way of parsing an actual custom tree without ignoring errors. What i propose is to change the signature of the generate function to allow the user to pass a generic that specifies the shape of it's own ast.

Something like this

Expected behavior

I would love to specify extra nodes of my Ast without incurring in ts errors.

davidbonnet commented 3 months ago

Thanks @paoloricciuti for mentioning this. The types could indeed be enhanced by making the Options type generic with inferred arguments (this means that Output should extend the necessary stream interface if defined).

Feel free to suggest a pull request.

paoloricciuti commented 3 months ago

Thanks @paoloricciuti for mentioning this. The types could indeed be enhanced by making the Options type generic with inferred arguments (this means that Output should extend the necessary stream interface if defined).

Feel free to suggest a pull request.

Sure, I'll try to open a PR later on :)