---
title: Module Alias Declaration
tags: RBS
---
# Module Alias Declaration
This proposal is to add a *module alias declaration* to RBS language. The feature has been requested [in 2020](https://github.com/ruby/rbs/issues/345), and [I also found a Ruby code that needs this feature](https://github.com/ruby/gem_rbs_collection/pull/281).
```rbs=
# Make ::HashWithIndifferentAccess an alias of ActiveSupport::HashWithIndiffirentAccess
class HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
# Define ActiveRecord::Type::* types that are aliases of ActiveModel types
module ActiveRecord
module Type
class BigInteger = ActiveModel::Type::BigInteger
class Binary = ActiveModel::Type::Binary
class Boolean = ActiveModel::Type::Boolean
class Decimal = ActiveModel::Type::Decimal
class Float = ActiveModel::Type::Float
class Integer = ActiveModel::Type::Integer
class String = ActiveModel::Type::String
class Value = ActiveModel::Type::Value
end
end
```
## Syntax
The syntax is defined as the following:
```
module_alias_declaration ::= `class` _type_name_ `=` _type_name_
| `module` _type_name_ `=` _type_name_
```
Note that a module alias is a relation between a module name and another module name.
```rbs
module Foo = Kernel # Valid
class StringArray = Array[String] # RHS cannot be a type application
class MyHash[K, V] = Hash[K, V] # LHS cannot be a generic type
```
The type name at the right hand side can be a relative name that is interpreted same as other relative type names.
## Validation
We have several limitations of the usage of module aliases.
1. The module alias can be used as a type name in many places, but it cannot be used in left-hand-side-ish position of other declarations.
```rbs
class HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
# Error: opening an alias module is prohibited
class HashWithIndifferentAccess
end
# Error: adding types under an alias module is prohibited
HashWithIndifferentAccess::t = String
```
2. The alias declarations must have correct keyword `class`/`module` that matches to the right hand side.
```rbs
class Foo = ::Kernel # Error: Kernel is a module
module Bar = ::BasicObject # Error: BasicObject is a class
```
3. A module alias cannot be cyclic.
```rbs=
class Foo = Bar
class Bar = Foo # Error: cyclic definition
```
## API
The APIs provided by RBS library automatically normalizes the module aliases.
* `DefinitionBuilder` returns `Definitions` of the normalized classes automatically
* The `#type_name` and `#self_type` of the definition may differ from the given type name to `#build_singleton` or `#build_instance`
* The normalization works for outer namespaces and ancestors
* Type names are not normalized
* `Resolver::TypeNameResolver` works for alias names. It returns absolute names of the class aliases.
* `Environment` provides *normalize* methods
## Limitations
The alias cannot be used to describe the *left-hand-side* of the declarations.
```rbs
class Foo = String
class Foo # Cannot open the aliased class
end
type Foo::bar = Integer # Cannot add a type alias
```