Skip to content

fix: resolve TypeScript built-in type name collisions in CRD imports - #3801

Open
mateo-moon wants to merge 3 commits into
cdk8s-team:2.xfrom
mateo-moon:fix/builtin-type-name-collision
Open

fix: resolve TypeScript built-in type name collisions in CRD imports#3801
mateo-moon wants to merge 3 commits into
cdk8s-team:2.xfrom
mateo-moon:fix/builtin-type-name-collision

Conversation

@mateo-moon

@mateo-moon mateo-moon commented Feb 3, 2026

Copy link
Copy Markdown

Summary

Fixes #3800

When a CRD's kind name matches a TypeScript built-in utility type (e.g., Record, Map, Set), the generated code creates a class that shadows the built-in type. This causes TypeScript compilation errors when the generated toJson_* functions use types like Record<string, any>.

Changes

Added a post-processing step in src/import/crd.ts that:

  1. Maintains a list of TypeScript built-in utility types that may conflict
  2. Detects when a CRD kind matches one of these types
  3. Adds a type alias (e.g., type JsonRecord<K extends keyof any, T> = { [P in K]: T };) at the beginning of the generated file
  4. Replaces usages of the built-in type with the alias (e.g., Record<string, any>JsonRecord<string, any>)

Example

For Cloudflare's DNS Record CRD, the generated code now includes:

// Type alias to avoid collision with the Record class defined below
type JsonRecord<K extends keyof any, T> = { [P in K]: T };

export class Record extends ApiObject {
  // ...
}

export function toJson_RecordProps(obj: RecordProps | undefined): JsonRecord<string, any> | undefined {
  // ...
}

Test Plan

  • Verified TypeScript compilation passes
  • Manual testing with Cloudflare DNS Record CRD
  • Consider adding unit tests for the fixBuiltinTypeConflicts function

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

auto-merge was automatically disabled February 3, 2026 11:48

Head branch was pushed to by a user without write access

@mateo-moon
mateo-moon force-pushed the fix/builtin-type-name-collision branch 2 times, most recently from c5b25e3 to 3cdaf99 Compare February 3, 2026 11:52
When a CRD's kind name matches a TypeScript built-in utility type (e.g.,
"Record", "Map", "Set"), the generated code creates a class that shadows
the built-in type. This causes TypeScript compilation errors when the
generated toJson functions use types like `Record<string, any>`.

This fix adds a post-processing step that:
1. Detects when a CRD kind matches a TypeScript built-in type
2. Adds a type alias (e.g., `JsonRecord<K, T>`) to preserve the built-in
3. Replaces usages of the built-in type with the alias

Example: Cloudflare's DNS `Record` CRD would generate a `Record` class,
and `Record<string, any>` usages are replaced with `JsonRecord<string, any>`.

Signed-off-by: OP <op@cicd.ninja>
@mateo-moon
mateo-moon force-pushed the fix/builtin-type-name-collision branch from 3cdaf99 to caa1b79 Compare July 19, 2026 14:02
@mateo-moon

Copy link
Copy Markdown
Author

Rebased onto the current 2.x head. While running this patch in production we found three follow-up issues, and the fixes are now included here: the type alias is emitted only once for multi-version CRDs, runtime calls such as Object.entries/keys/values are redirected to a preserved _Object alias, and those runtime replacements are applied to every CRD generated into the same file. The full local test suite passes. This still addresses #3800, which remains open. @iliapolo could you approve the workflow run and review?

When a CRD kind is 'Object', the generated class shadows globalThis.Object,
breaking Object.entries(), Object.keys(), Object.assign() etc. in toJson
functions. Now we emit 'const _Object = globalThis.Object;' and replace
all runtime static method calls with the alias.

Signed-off-by: OP <op@cicd.ninja>
When a CRD kind like 'Object' shadows a global constructor, the class
definition affects ALL code in the generated file, not just code for
that specific CRD. Previously, fixBuiltinTypeConflicts only replaced
runtime calls (Object.entries, etc.) for the CRD whose kind matched
the builtin. Now it collects all conflicting kinds at the file level
and applies replacements to all CRDs in the same API group module.

This fixes ProviderConfig's toJson functions in
kubernetes.crossplane.io.ts where Object.entries was not being
replaced even though class Object is defined earlier in the file.

Signed-off-by: OP <op@cicd.ninja>
@mateo-moon
mateo-moon force-pushed the fix/builtin-type-name-collision branch from caa1b79 to 41a2254 Compare July 19, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CRD import fails when kind name matches TypeScript built-in type (e.g., Record)

1 participant