Skip to Content

typeof and nameof

Two compile-time introspection expressions: typeof(T) gets the Type value of a type, and nameof(x) folds a name into a string constant.

typeof: The Value of a Type

typeof(T) produces the Type value of the type T; it can be compared, passed around, and stored in a constant:

func main() -> int { print(typeof(int) == typeof(int), typeof(string) == typeof(int)); return 0; }
True False

The same type always produces the same Type value, and different types are unequal. The members of Type values, the value-side mapping, and Field reads and writes are covered in Reflection; for lightweight runtime type checks you can also use is (see Any).

nameof: A Name as a String

nameof(x) folds a name into a string constant that follows renames automatically:

const Who: string = nameof(Answer); func Answer() -> int => 42; func main() -> int { print(nameof(Who)); return 0; }
Who
  • nameof(x), nameof(obj.Member), nameof(TypeName), and nameof(Mod::Sym) are all legal and fold to the name’s string;
  • Being a constant, it can serve as a const initializer, an attribute argument, or a case label;
  • A misspelled name is reported as undefined at compile time, which is safer than a hand-written string.

Notes

  • Only the adjacent identifier + ( form is intercepted as a nameof call; everywhere else nameof is an ordinary identifier;
  • The typeof operand must be a type name; write generic instantiations in full (typeof(list<int>));
  • nameof folds at compile time and leaves only a string constant in the artifact; typeof produces interned Type values, and the same type always yields the same value.
Last updated on October 11, 2026