Typescript-go does not infer large generics due to maximum length compiler will serialize
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.
Do you have a self contained example we could test?
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
})()
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.
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...
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.
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.