Visibility controls which declarations can be referenced from outside their containing class or space.
Typical does not place visibility keywords before declarations. Visibility is stored in visibility groups inside the containing scope.
💡 User (
name is string
id is string
displayName() is string (
return name
)
export (
displayName
)
expose (
id
)
)
The editor should usually render visibility as a badge or control attached to the declaration rather than showing the visibility group in the normal code flow. Visibility groups are the canonical file representation.
The editor may use these icons for visibility:
| Icon | Visibility |
|---|---|
| ↑ | export |
| ← | expose |
| ↓ | extend |
| exclude |
Visibility Groups
Typical has four visibility groups:
| Group | Meaning |
|---|---|
| export | Visible outside the current space and included in the public API when the compilation unit is a library. |
| expose | Visible outside the current space, but not included in the public API. |
| extend | Visible to child classes. Not included in the public API. |
| exclude | Explicitly private. Used when a declaration should remain visible only inside its containing class or space, or when a constructor parameter should be promoted privately. |
| none | If a declaration is not listed in a visibility group, it is visible only inside its containing class or space. This is the default visibility for all declarations. |
Only one export, one expose, one extend, and one exclude group may appear in a scope.
export (
Member1
Member2
)
expose (
Helper
cacheKey
)
extend (
secret
)
exclude (
privateState
)
Visibility groups may appear anywhere in a scope. The editor saves them at the bottom of the scope.
Valid Scopes
Visibility groups may appear inside spaces and classes.
The top level of a file is treated as a top-level space, so visibility groups are also valid at the top level.
Classes include ordinary classes, extension classes, and primitive classes. Static scopes do not have separate visibility groups. Static members are listed in the containing class's visibility groups.
💡 Factory (
static (
create() (
return Factory()
)
)
export (
create
)
)
Group Members
Visibility groups may name fields, functions, properties, constructors, classes, top-level functions, and top-level identifiers.
Constructors are referenced as constructor.
💡 User (
constructor(name is string) (
this.name = name
)
export (
constructor
)
)
Constructor overloading is not supported, so constructor is unambiguous.
Constructor Parameter Promotion
Constructor parameters may be promoted to class properties by listing the parameter name in a visibility group. The constructor page defines the full promotion behavior.
💡 Bunny (
constructor(
a is string
b is string
c is string) (
)
export (
constructor
a
b
)
expose (
c
)
)
In this example, a, b, and c are constructor parameters promoted to properties. a and b are exported properties. c is an exposed property.
Use exclude to promote a constructor parameter to a private property.
When resolving a visibility group entry inside a class, Typical first looks for a matching class member that is not part of the constructor. If one exists, the visibility group applies to that member.
If no matching class member exists, Typical then looks for a matching constructor parameter. If one exists, the constructor parameter is promoted to a property with that visibility.
💡 User (
id is string
constructor(id is string, name is string) (
this.id = id
)
export (
id
name
)
)
In this example, id applies to the existing field. name promotes the constructor parameter to an exported property.
Inherited members are considered class members for this lookup. If a constructor parameter has the same name as an inherited member, the visibility group applies to the inherited member and does not promote the constructor parameter.
A promoted constructor parameter cannot also be declared as a separate property or field in the same class. That creates a duplicate member conflict.
Properties may be referenced by property name or by accessor.
💡 User (
get name() is string (
return firstName + " " + lastName
)
set name(value is string) (
...
)
export (
name
)
expose (
get name
)
)
When a property name is listed directly, the visibility applies to both the getter and setter. get name applies only to the getter. set name applies only to the setter.
Fields and functions cannot share a name in the same scope, so ordinary names are unambiguous.
Ghosts do not participate in visibility groups because they are not called or referenced as ordinary API members.
Imported bindings do not participate in visibility groups. Only items explicitly defined in the current space may be exported from it, so imported modules cannot be exported or re-exported.
Generated wrapper modules expose their representable Rust API implicitly. That wrapper surface is determined by wrapper generation rather than Typical visibility groups.
Resolution
A visibility group may refer to a declaration that appears later in the same scope.
export (
User
)
💡 User (
)
If a group names something that is not declared in the same scope, the compiler generates a notice.
If the same declaration appears in more than one visibility group in the same scope, the compiler generates a notice. As a recovery fallback, the last group wins.
export (
name
)
expose (
name
)
In this example, name is treated as expose.
Containing Visibility
A containing class or space sets the effective visibility ceiling for its contents.
💡 Internal (
value is string
export (
value
)
)
The value member may request export, but it cannot be more visible in practice than Internal. The compiler may generate a notice when a requested visibility exceeds its containing visibility.
This rule lets the editor preserve a member's desired visibility even when the containing class or space is currently less visible.
Inherited Members
A child class may list an inherited member in a visibility group.
💡 Base (
value is string
)
💡 Child is Base (
export (
value
)
)
A child class may widen inherited visibility. It cannot narrow inherited visibility.
Separators
Visibility group entries use the standard Typical separator rules. Entries may be separated by newlines, commas, or both.
export (A, B, C)
export (
A
B
C
)
export (
A, B
C
)