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 FalseThe 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;
}Whonameof(x),nameof(obj.Member),nameof(TypeName), andnameof(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
