Type Reflection

In programming languages reflection is the ability of a program to examine and modify its own structure and behavior. In Move, there's a limited form of reflection that allows you to inspect the type of a value at runtime. This is useful when you need to store type information in a homogeneous collection, or when you need to check if a type belongs to a package.

Type reflection is implemented in the Standard Library module std::type_name. Expressed very roughly, it gives a single function get<T>() which returns the name of the type T.

In practice

The module is pretty straightforward, and operations allowed on the result are limited to getting a string representation and extracting the module and address of the type.

module book::type_reflection;

use std::ascii::String;
use std::type_name::{Self, TypeName};

/// A function that returns the name of the type `T` and its module and address.
public fun do_i_know_you<T>(): (String, String, String) {
    let type_name: TypeName = type_name::get<T>();

    // there's a way to borrow
    let str: &String = type_name.borrow_string();

    let module_name: String = type_name.get_module();
    let address_str: String = type_name.get_address();

    // and a way to consume the value
    let str = type_name.into_string();

    (str, module_name, address_str)
}

#[test_only]
public struct MyType {}

#[test]
fun test_type_reflection() {
    let (type_name, module_name, _address_str) = do_i_know_you<MyType>();

    //
    assert!(module_name == b"type_reflection".to_ascii_string());
}

Further reading

Type reflection is an important part of the language, and it is a crucial part of some of the more advanced patterns.