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

Programmatic generation of curried interfaces for custom kinds #62

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

MajorLift
Copy link
Collaborator

@MajorLift MajorLift commented Sep 16, 2023

Current example output

// outputInterfaces(name: string, numParams: number): InterfaceDeclaration[]
[
  'export interface ExampleKind extends Kind.Kind {\n' +
    '    f(x: Type._$cast<this[Kind._], unknown>): ExampleKind_T1<typeof x>;\n' +
    '}',
  'interface ExampleKind_T1<X1 extends unknown> extends Kind.Kind {\n' +
    '    f(x: Type._$cast<this[Kind._], unknown>): ExampleKind_T2<X1, typeof x>;\n' +
    '}',
  'interface ExampleKind_T2<X1 extends unknown, X2 extends unknown> extends Kind.Kind {\n' +
    '    f(x: Type._$cast<this[Kind._], unknown>): ExampleKind_T3<X1, X2, typeof x>;\n' +
    '}',
  'interface ExampleKind_T3<X1 extends unknown, X2 extends unknown, X3 extends unknown> extends Kind.Kind {\n' +
    '    f(x: Type._$cast<this[Kind._], unknown>): _$exampleKind<X1, X2, X3, typeof x>;\n' +
    '}'
]

Progress

  • Generates InterfaceDeclarations with correct naming scheme (e.g. _T1, _T2), ordering, and function signatures.
  • Inject type constraints for all parameters (currently defaults to unknown).
    • Dynamically generate factory code,
    • OR update interface declaration with ts-morph.
  • Import hkt-toolbelt submodules required to express type constraints.
  • Access existing _$ implementation.
    • Stringify and inject into source file,
    • OR import from separate module.
  • Emit/output as a module that can be used locally without further configuration.

References

@MajorLift MajorLift changed the title stash Programmatic generation of curried custom kind interfaces Sep 16, 2023
@MajorLift MajorLift changed the title Programmatic generation of curried custom kind interfaces Programmatic generation of curried interfaces for custom kinds Sep 16, 2023
@poteat
Copy link
Owner

poteat commented Sep 17, 2023

I love this! This is a really good idea for ensuring the codebase is consistent. I wonder if there isn't a TS Hygienic Macro framework or extension that we could utilize? That would mean we could separate out the "abstraction" of using code to generate code onto the macro system.

@MajorLift
Copy link
Collaborator Author

Good to hear that you agree this could be useful!

It looks like there aren't that many options for TypeScript macros, and this is pretty much the only one that's being actively maintained: https://github.com/GoogleFeud/ts-macros.

It does look pretty promising, and there's even a playground, which should make it easy to experiment with: https://googlefeud.github.io/ts-macros/. I'll look into whether we can use it for this PR.

@MajorLift MajorLift added enhancement New feature or request DO-NOT-MERGE labels Nov 26, 2023
@MajorLift MajorLift self-assigned this Nov 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DO-NOT-MERGE enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Research programmatic generation of custom kinds with AST manipulation
2 participants