typeof

The typeof expression returns the type of an expression:

  1. a = 1
  2. b = typeof(a) # => Int32

It accepts multiple arguments, and the result is the union of the expression types:

  1. typeof(1, "a", 'a') # => (Int32 | String | Char)

It is often used in generic code, to make use of the compiler’s type inference capabilities:

  1. hash = {} of Int32 => String
  2. another_hash = typeof(hash).new # :: Hash(Int32, String)

Since typeof doesn’t actually evaluate the expression, it can be used on methods at compile time, such as in this example, which recursively forms a union type out of nested generic types:

  1. class Array
  2. def self.elem_type(typ)
  3. if typ.is_a?(Array)
  4. elem_type(typ.first)
  5. else
  6. typ
  7. end
  8. end
  9. end
  10. nest = [1, ["b", [:c, ['d']]]]
  11. flat = Array(typeof(Array.elem_type(nest))).new
  12. typeof(nest) # => Array(Int32 | Array(String | Array(Symbol | Array(Char))))
  13. typeof(flat) # => Array(String | Int32 | Symbol | Char)

This expression is also available in the type grammar.