ts-morph icon indicating copy to clipboard operation
ts-morph copied to clipboard

Feature request: make all wrapper factory functions public

Open jedwards1211 opened this issue 2 years ago • 4 comments

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

As mentioned in #1418, #1421 there are cases where we need essential information deep inside the compiler types that we can't navigate to with the ts-morph API, like type.origin.

In many cases type.compilerType would be sufficient to work with. But this became a roadblock for us because we started out with a recursive function that takes a ts-morph Type wrapper and generates zod schema declarations, and now realized we'd like to call it on type.compilerType.origin in some cases where TS is flattening unions of type aliases and enums. So we either have to refactor our function to use raw TS compiler API or get a ts-morph wrapper for type.compilerType.origin.

In general, not being able to go from compiler object to wrapper seems prone to becoming a roadblock like this, so I think all of the wrapper factory functions should be exposed.

If only Type._context were not @internal then we could do type._context.compilerFactory.getType(type.compilerType.origin) and keep going. I feel on the fence about whether to basically do that and suppress errors since that API isn't in the .d.ts, or just use plain TS compiler API everywhere.

But it would be a bummer not to be able to use ts-morph because it's been really nice and convenient up to this point 🙂

Describe the solution you'd like

CompilerFactory being officially public API, or at least some public way to get a wrapper for every compiler object type.

Describe alternatives you've considered

jedwards1211 avatar Jun 14 '23 19:06 jedwards1211

@jedwards1211 are you trying to inline zod types ?

// Initial declaration file
import { z } from 'zod';
declare const zAgentStatus: z.ZodEnum<["Login", "Logout", "Available", "Break"]>;
export declare type AgentStatus = z.infer<typeof zAgentStatus>;

// becomes
export declare type AgentStatus = 'Login' | 'Logout' | 'Available' | 'Break';

JesusTheHun avatar Jul 12 '23 11:07 JesusTheHun

@JesusTheHun I understand z.infer, z.output, z.input etc. But we're intentionally building a tool that works in the opposite direction, from export type AgentStatus = 'Login' | 'Logout' | 'Available' | 'Break' it generates another file with export const AgentStatus = z.enum(["Login", "Logout", "Available", "Break"]).

jedwards1211 avatar Jul 12 '23 15:07 jedwards1211

This package doesn't do the job well enough ?

JesusTheHun avatar Jul 12 '23 16:07 JesusTheHun

Nope from what I can tell it statically analyzes the AST; that approach is very limited compared to inspecting the types computed by typescript. What we're building is able to handle a lot more kinds of mapped types. I only mentioned our use case to provide some concrete detail of when it becomes necessary to go from TS objects back to wrappers; I want to stick to discussing how to enable this in ts-morph.

jedwards1211 avatar Jul 21 '23 03:07 jedwards1211