Skip to content

Add support for augmenting classes with existing types using includes type syntax #1589

@TwitchBronBron

Description

@TwitchBronBron

Feature Request: Add includes type <TypeExpression> for Class and Interface Augmentation

Justification

Today, there is no way to augment classes or interfaces with the members of existing types in BrighterScript. While developers can (eventually) use implements, these mechanisms either require explicit definitions or don't provide type compatibility for native/complex objects. Introducing includes type enables more flexible and robust code organization and integration with build-time/runtime code modifications, including:

1. Improved native type interoperability

  • Roku classes (and most custom classes) use associative arrays under the hood. Many devs want to be able to call roAssociativeArray (or similar) functions directly on their classes without needing explicit type casts everywhere.
  • Example: A class MyMap transparently exposes roAssociativeArray functionality to support its real runtime shape for methods like .Append(), or .Count().

2. Enhanced build system and preprocessor workflows

  • In some advanced build setups, a preprocessor injects properties/methods into classes at runtime. With this feature, devs would not need to redundantly define or maintain those properties in every type definition.
  • Reduces maintenance overhead and risk of type mismatches, code duplication, or missing/overridden props.

Feature Proposal

Add a new top-level statement for classes and interfaces:

class MyClass
    includes type roAssociativeArray
    includes type MyInterface
    includes type MyEnum
end class
  • Syntax must include both includes and type tokens
  • Supported targets:
    • Native interfaces (e.g., roDateTime, ifArray)
    • Custom interfaces (e.g. TestFrameworkCommonProps)
    • Other classes
    • Enums (class receives all enum members as own properties)
  • Unsupported and should be an error:
    • Standalone functions (e.g., includes type MyFunction)
    • Namespaces (e.g., includes type MyNamespace)
  • These statements must be at the top of a class or interface, not mixed in among code
  • Trigger a compile warning or error for colliding/incompatible function signatures as a result of includes
  • Helpful diagnostics for unsupported expressions and clear docs covering these points

Examples: includes type <TypeExpression>

1. Native interface/associative array (roAssociativeArray)

class MyDictionary
    includes type roAssociativeArray
end class

' MyDictionary now exposes functions like Count(), AddReplace(), etc. without explicit type casting

2. Custom interface

interface Timestamped
    lastModified as DateTime
    updateTimestamp() as void
end interface

class MyResource
    includes type Timestamped
end class

' MyResource will require lastModified and updateTimestamp, and gets their types in completions/typechecking

3. Including another class

class SharedLogic
    public someProp as string
    function sharedThing() : void
    end function
end class

class SpecialThing
    includes type SharedLogic
end class

' SpecialThing has `sharedThing()` and `someProp` as a member for typechecking, docs, etc.

4. Enum inclusion

enum Color
    Red
    Green
    Blue
end enum

class ColorPicker
    includes type Color
end class

' ColorPicker gets properties Red, Green, Blue (from the enum) and can use them as typed values.

5. Invalid: Namespace

class MyType
    includes type MyNamespace
end class

' Error: Cannot include namespace. Only class, interface, enum are supported.

6. Invalid: Function

function Add(a as integer, b as integer) as integer
    return a + b
end function

class Calculator
    includes type Add
    ' ~~~~~~~~~~~ ' Error: Cannot include a function directly. Only class, interface, enum are supported.
end class

7. Misplaced: not at top of class

class Offender
    function foo()
    end function
    includes type roAssociativeArray
    '~~~~~~~~~~~~~~~~~~~ Error: must be at the top of the class or interface, before any functions or fields.
end class

8. Collisions show a warning or error

interface Testable
    function test(p1 as integer)
    end function
end interface

class Offender
    includes type Testable
    '~~~~~~~~~~~~~ Error: the functions 'test' are incompatible                        
    function test(p1 as string, p2 as boolean)
    end function
end class

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions