Skip to content

Support custom type assignability for complex types #1248

@a-hilaly

Description

@a-hilaly

Feature request checklist

  • There are no issues that match the desired change
  • The change is large enough it can't be addressed with a simple Pull Request
  • If this is a bug, please file a Bug Report.

Title: Support structural type comparison for complex types

Change

Hey folks! In kro we do use CEL to type-check expressions against expected types inferred from OpenAPI specs. Each type gets a path based name based on where it appears in the schema.

Our issue is that CEL compares types by name, not structure. Two types with identical fields but different names are considered incompatible. This causes problems in places like ternary expressions where both branches have the same structure but different type names.

We currently have a AreTypesStructurallyCompatible function that compares types by structure (fields, element types, etc..) rather than names. But this only works outside of CEL's Check() - we use it to validate expression outputs against expected types. And we can't hook into CEL's internal type comparisons, so things like ternary validation fail before we get a chance to run our check.

Would it be technically feasible to expose a hook or option for custom type assignability logic for complex types (lists, maps, structs)? We'd be happy to help with the implementation if you think this would be valuable for CEL.

Example

has(a.spec.items) ? a.spec.items : b.spec.items

Both lists have the same element structure, but CEL rejects this because the type names differ.

Alternatives considered

We tried assigning the same type name to structurally equivalent types (via hashing the structure), but this doesn't work for partially compatible structures. Using dyn() works as a user workaround but loses type safety.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions