Skip to content

Type introspection#

Types are first-class in CEL. type() returns the type of a value at runtime.

Basic types#

type(42)
// result: int (type)
type(3.14)
// result: double (type)
type("hello")
// result: string (type)
type(true)
// result: bool (type)
type(b"hello")
// result: bytes (type)
type(null)
// result: null_type (type)

Collection types#

type([1, 2, 3])
// result: list (type)
type({"a": 1})
// result: map (type)

Protocol Buffer types#

Protocol Buffer messages return their fully qualified type name.

// input: user = example.v1.User{name: "Alice"}
type(user)
// result: example.v1.User (type)
type(duration("1h"))
// result: google.protobuf.Duration (type)
type(timestamp("2023-01-01T00:00:00Z"))
// result: google.protobuf.Timestamp (type)

Type comparison#

Compare types using equality operators.

type(42) == int
// result: true (bool)
type("hello") == string
// result: true (bool)
type([1, 2, 3]) == list
// result: true (bool)

Dynamic values#

type() resolves the actual runtime type even when dyn() is used.

type(dyn(42))
// result: int (type)
type(dyn("hello"))
// result: string (type)

This is useful with ternary expressions that return different types. The dyn() wrapper allows the ternary to type-check, and type() reveals the actual result type.

type(true ? dyn(42) : dyn("hello"))
// result: int (type)
type(false ? dyn(42) : dyn("hello"))
// result: string (type)

Type of type#

The result of type() is itself a value with its own type.

type(type(42))
// result: type (type)

See also#