# Types and properties
Every value has a `.type`. A type value has a `.name`, which names the type it
represents. Asking a type value for `.type` gives `Type`.
```shy
let $numbers = [10, 20]
echo $numbers.type.name $numbers.value_type.name
echo Integer.name Integer.type.name
```
```text
Array Integer
Integer Type
```
Exact type identity is useful for guards: a distinct `type Height = Integer`
has type `Height`, rather than `Integer`. Broad constraints such as `Number`
and `any` remain useful in annotations without changing identity tests.
## Inspect an object
`.properties` returns `[String: any]`. Struct fields appear as values. Other
values expose a `value` entry; collection values retain their collection shape.
All values expose `type`, enums expose `index`, and available methods appear as
bound function references. Inspecting a method does not execute it.
```shy
let $word = "moss"
let $members = $word.properties
let $length = $members["count"]
echo $members["value"] ($length)
```
```text
moss 4
```
Getter-style properties are represented without executing user getters during
inspection. Actual fields win name collisions. Receiver-free conversion factories
belong to the represented type's interface rather than an instance receiver.
`next_item` is part of the available interface too.
## Inspect a type's interface
`ExecResult.properties` describes the represented type, not a made-up default
instance. Field entries describe declared types; function entries describe their
prototypes, including factories. `Type.properties` describes `Type` itself.
The prelude's `.print_properties` formats this information for exploration:
```text
Integer.print_properties
ExecResult.print_properties
[Integer].print_properties
```
Property hashes have no guaranteed display order. Use their named entries when
writing logic rather than depending on the pretty printer's ordering.
---
Related: [Methods](Methods-and-Properties) · [Type guards](Match-and-Type-Guards) · [Named types](Named-Types-and-Unions)