Static type checker for CEL expressions.
Validates that a parsed AST is well-typed given declared variable types. This is an optional step -- CEL expressions can be evaluated without type-checking, but checking catches errors earlier.
Supports full CEL type inference including wrapper types, message types, well-known types, abstract types (optionals), type parameters for overload resolution, and proto field lookups.
Usage
{:ok, ast} = Celixir.parse("x + 1")
declarations = %{"x" => :int}
:ok = Celixir.Checker.check(ast, declarations)
# With full type environment:
env = %{
variables: %{"x" => :int},
functions: %{"myFunc" => [%{id: "myFunc_int", params: [:int], result_type: :bool}]},
container: nil
}
:ok = Celixir.Checker.check(ast, env)
Summary
Functions
Converts internal bottom types to :dyn in the final output.
Call this on the result of infer/2 before comparing with expected types.
Returns the checker type for a known proto message field.
Falls back to :dyn for unknown messages/fields.
Resolves the best matching overload for a function call given argument types. Returns the result type with type parameter substitution applied.
Unifies two CEL types. Returns the most specific common type.
Types
@type cel_type() :: :int | :uint | :double | :bool | :string | :bytes | :null_type | :timestamp | :duration | :dyn | {:list, cel_type()} | {:map, cel_type(), cel_type()} | {:wrapper, atom()} | {:message, String.t()} | {:well_known, atom()} | {:abstract, String.t(), [cel_type()]} | {:type_param, String.t()} | :type | :error
Functions
@spec check(Celixir.AST.expr(), map()) :: :ok | {:error, String.t()}
Converts internal bottom types to :dyn in the final output.
Call this on the result of infer/2 before comparing with expected types.
@spec infer(Celixir.AST.expr(), map()) :: cel_type() | {:error, String.t()}
Returns the checker type for a known proto message field.
Falls back to :dyn for unknown messages/fields.
Resolves the best matching overload for a function call given argument types. Returns the result type with type parameter substitution applied.
Unifies two CEL types. Returns the most specific common type.
CEL-specific: :dyn is the least specific type — when one side is :dyn,
the other side wins.