mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
RFC: Type Namespaces
This commit is contained in:
parent
0b2755f964
commit
90447d7291
1 changed files with 92 additions and 0 deletions
92
rfcs/type-namespaces.md
Normal file
92
rfcs/type-namespaces.md
Normal file
|
@ -0,0 +1,92 @@
|
|||
# Type Namespaces
|
||||
|
||||
## Summary
|
||||
|
||||
Add user syntax to define namespaces for type declarations.
|
||||
|
||||
## Motivation
|
||||
|
||||
When working with multiple modules in a project, it is common for users to use a separate module solely for containing type declarations to avoid having cyclic requires in the typechecker. One of these modules may look like this:
|
||||
|
||||
```lua
|
||||
export type ShapeType = "Triangle" | "Square" | "Circle"
|
||||
|
||||
export type ObjectParams = {
|
||||
Name: string,
|
||||
Shape: ShapeType,
|
||||
Position: Vector3
|
||||
}
|
||||
|
||||
return nil
|
||||
```
|
||||
|
||||
An added benefit of this pattern is that, when the above module is required, a namespace is created for the exported types in the module's name:
|
||||
|
||||
```lua
|
||||
local Types = require("Types")
|
||||
|
||||
local MyShape: Types.ShapeType = "Circle"
|
||||
|
||||
local Object = {
|
||||
Name = "MyObject",
|
||||
Shape = MyShape,
|
||||
Position = Vector3.zero
|
||||
} :: Types.ObjectParams
|
||||
```
|
||||
This RFC aims to streamline defining type namespaces like the above without having to use modules as well as allowing for multi-dimensional namespaces to help organize large projects (i.e., `Types.Shape.ObjectParams`).
|
||||
|
||||
## Design
|
||||
|
||||
Namespaces could be added to any type declaration via a dot to discern between space name and type name:
|
||||
|
||||
```lua
|
||||
type Space.Name = number
|
||||
|
||||
local Foo: Space.Name = 1
|
||||
```
|
||||
|
||||
This syntax could also allow for nested namespaces as well as generated namespaces for exported types:
|
||||
|
||||
```lua
|
||||
export type Types.Space.Name<A, B> = A | B
|
||||
```
|
||||
|
||||
## Drawbacks
|
||||
|
||||
This syntax design may introduce repetition for multiple types as it is by declaration-basis. For example:
|
||||
|
||||
```lua
|
||||
export type Space.Foo = number | string
|
||||
export type Space.Bar = "Hello" | "World"
|
||||
export type Space.Baz = boolean
|
||||
```
|
||||
|
||||
Mistypes could confuse users as they create a new namespace for the type:
|
||||
|
||||
```lua
|
||||
export type Space.A = number
|
||||
export type Spaze.B = string
|
||||
```
|
||||
|
||||
Nested spaces could also confuse users since namespaces could be mingled with actual types:
|
||||
|
||||
```lua
|
||||
local Foo: Space.Foo = 1
|
||||
local Bar: Space.Bar.Foo = true
|
||||
```
|
||||
|
||||
## Alternatives
|
||||
|
||||
Using the `in` keyword instead:
|
||||
|
||||
```lua
|
||||
type Name in Space = number
|
||||
```
|
||||
|
||||
Having overarching syntax for namespaces:
|
||||
|
||||
```lua
|
||||
export Space
|
||||
type foo = number,
|
||||
type bar = string
|
||||
```
|
Loading…
Add table
Reference in a new issue