Skip to content

Feedback on genType generated outputs #6332

Closed as not planned
Closed as not planned
@sgrove

Description

@sgrove

While trying to implement a local tooling pipeline, it seems that it's not quite possible to achieve the same fidelity as hand-written TypeScript definition files.

Given the following demo.res file:

// Demo.res
@genType @ocaml.doc("A module for deciding on a subject matter for a poem.")
module DecideSubject = {
  @genType.as("payload")
  type payload = {
    @genType.as("hint") @ocaml.doc("A hint to use as a guide when thinking of your poem.")
    hint: string,
  }
  @genType.as("input") @ocaml.doc("The input used to generate the prompt and system prompt.")
  type input
  @genType.as("output") @ocaml.doc("The output from evaluating the llm prompt")
  type output = {
    @genType.as("text") @ocaml.doc("The text of the poem.")
    text: string,
    @genType.as("prompt") @ocaml.doc("The prompt used to generate the poem.")
    prompt: string,
    @genType.as("systemPrompt") @ocaml.doc("The system prompt used to generate the poem.")
    systemPrompt: string,
  }

  @genType @ocaml.doc("Decide on a subject matter for a poem.")
  let _placeholder = (
    @ocaml.doc("The runner specification") run: string,
    @ocaml.doc("The number of times to cycle through the runner") times: int,
  ) => (run, times)->ignore
}

We get out the the Demo.gen.tsx file (I've elided the preamble to just show the relevant parts):

// demo.gen.tsx
// tslint:disable-next-line:interface-over-type-literal
export type DecideSubject_payload = { readonly hint: string };
export type payload = DecideSubject_payload;

// tslint:disable-next-line:max-classes-per-file
export abstract class DecideSubject_input {
  protected opaque!: any;
} /* simulate opaque types */
export type input = DecideSubject_input;

// tslint:disable-next-line:interface-over-type-literal
export type DecideSubject_output = {
  readonly text: string;
  readonly prompt: string;
  readonly systemPrompt: string;
};
export type output = DecideSubject_output;

/** Decide on a subject matter for a poem. */
export const DecideSubject__placeholder: (run: string, times: number) => void =
  function (Arg1: any, Arg2: any) {
    const result = Curry._2(DemoBS.DecideSubject._placeholder, Arg1, Arg2);
    return result;
  };
  1. The docstrings don't carry over for each of the fields, so the consumer of the TypeScript library doesn't get on-hover support
  2. The output names can't be controlled (notice the const output: Demo.DecideSubject_output = {}; vs const output: Demo.DecideSubject.output = {}; in the usage code below
  3. Adding "generatedFileExtension": ".ts" to gentypeconfig in bsconfig.json will output .tsx files instead of .ts (this could be PEBKAC)
  4. The arguments in the placeholder function don't have any docstrings

Here's a screenshot of the pipeline and experience:

Screenshot 2023-07-26 at 11 58 57

Separately, potentially another PEBKAC (maybe mentioned under some special TypeScript mangling rules), the output Demo.bs.js:

// Generated by ReScript, PLEASE EDIT WITH CARE
"use strict";

function _placeholder(run, times) {}

var DecideSubject = {
  _placeholder: _placeholder,
};

exports.DecideSubject = DecideSubject;
/* No side effect */

Doesn't have DecideSubject__placeholder, but the generated types export it so it autocompletes, e.g. Demo.DecideSubject__placeholder("run", 1);

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleOld issues that went stale

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions