typescript-go icon indicating copy to clipboard operation
typescript-go copied to clipboard

Typescript-go does not infer large generics due to maximum length compiler will serialize

Open Raynos opened this issue 1 month ago • 5 comments

A bunch of generic types ( we use SStruct as a custom alternative to zod ) refuse to become inferred due to maximum length.

Steps to reproduce

workspaces/api-v0/src/schema/socket-report.ts:17:14 - error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.

17 export const SocketReport = new SStruct({

Behavior with [email protected]

No type error

Behavior with tsgo

I had to fix this with the manual code

export const SocketReport: SStruct<{
  id: SString
  healthy: SBoolean
  issues: typeof SocketIssueList
  score: SStruct<{
    avgSupplyChainRisk: SFloat
    avgQuality: SFloat
    avgMaintenance: SFloat
    avgVulnerability: SFloat
    avgLicense: SFloat
  }>,
  url: SString
}> = new SStruct({
  // TODO: not yet implemented
  // dependencies: new SArray(SocketReportDependency),
  id: new SString(''),
  healthy: new SBoolean(),
  issues: SocketIssueList,
  score: new SStruct({
    avgSupplyChainRisk: new SFloat(),
    avgQuality: new SFloat(),
    avgMaintenance: new SFloat(),
    avgVulnerability: new SFloat(),
    avgLicense: new SFloat(),
  }),
  url: new SString(''),
})

To me this manual inference doesn't seem to be reasonably within "maximum length" as it's an object with 5 fields and another nested object with 5 fields.

Each class referenced here like SString or SFloat or SStruct is an interface with 8 fields and then also a class implementing the interface with another 7 methods.

Raynos avatar Nov 11 '25 16:11 Raynos

Do you have a self contained example we could test?

jakebailey avatar Nov 18 '25 01:11 jakebailey

As I go about trying to make a self contained example I learned that

SocketIssueList contains an ungodly amount of nested references including

type IssueUnionSpec = {
  [K in IssueName]: SIntersection<
    [
      SStruct<{
        label: SString
        // version: SString
        description: SString
        severity: typeof SocketIssueSeverity
        category: typeof SocketCategory
        locations: typeof SocketRefList
        props: SStruct<IssueTypes[K]['props']>
      }>,
      SPartial<{
        usage: typeof SocketUsageRef
      }>,
    ]
  >
}
const WrappedIssues: IssueUnionSpec = (() => {
  const result: IssueUnionSpec = Object.create(null)
  for (const [issueType, issueSchema] of Object.entries(IssueTypes)) {
    result[issueType] = new SIntersection(
      SocketIssueBasics,
      new SStruct({
        description: new SString(''),
        props: new SStruct(issueSchema.props),
      }),
      new SPartial({
        usage: SocketUsageRef,
      }),
    )
  }
  return result
})()
Image

Including a K in type union over 120 unique string types.

I now understand why it ran into the inference limit because the actual type contains a messy fully enumerated array of union object types with 100+ variants.

Raynos avatar Nov 18 '25 12:11 Raynos

It's technically still a regression against typescript 5.x because it was incredibly tolerant of ridiculiously large unions with a lot of variants.

I gave up making a reproduction because I started copying code from 20 different files...

Raynos avatar Nov 18 '25 12:11 Raynos

Feel free to close as a breaking change, it would be nice to include the actual number of types in the error message next to maximum length though. I originally thought it was a reasonably small object, until I learned that it contained references to 200+ unique types from across 20 files..

If the error message contained the maximum number ( which is either 160, or 1_000_000 or other ) then I would have double checked and quickly seen that it's a silly nested type.

Raynos avatar Nov 18 '25 13:11 Raynos

Babel has also encountered this issue, and it seems to occur in recent versions. https://github.com/babel/babel/pull/17411 This issue can be reproduced by running yarn tsgo -b.

liuxingbaoyu avatar Nov 27 '25 17:11 liuxingbaoyu