Skip to content

Conversation

@markwpearce
Copy link
Collaborator

@markwpearce markwpearce commented Dec 15, 2025

Adds IntersectionType modelled after TypeScript's intersection types

  • Add IntersectionType
  • Add parsing for <type> and <type>
  • Allow "Grouped types" in parser (eg: (type1 or type2) and (type3 or type4))
  • Update type compatibility and other helpers to work with intersection types
  • Verify scope validation
  • Use order of operations on types, eg. type foo = myType1 or myType2 and myType3 or myType4 => myType1 or (myType2 and myType3) or myType4
  • Make sure type MyKlassAA = MyKlass and roAssociativeArray works properly
  • Test intersections with callfuncs
  • Add docs

expressionsWithOperator.push({ expression: expr });

// handle expressions with order of operations - first "and", then "or"
const combineExpressions = (opToken: TokenKind) => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially there is a better way of doing this...

This algorithm just gets a list of <type> <operator?>, and then first loops through it to combine all ands into binary expressions, then again to combine all ors

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in practice, this is fine, though

if (this.match(TokenKind.LeftCurlyBrace)) {
expr = this.inlineInterface();
} else if (this.match(TokenKind.LeftParen)) {
let left = this.previous();
Copy link
Collaborator Author

@markwpearce markwpearce Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type expression is a GroupingExpression, eg. (integer or float)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this github comment be better served as an actual in-code comment?

@markwpearce markwpearce marked this pull request as ready for review January 12, 2026 20:58
@markwpearce markwpearce added this to the v1.0.0 milestone Jan 13, 2026
@markwpearce
Copy link
Collaborator Author

Accomplishes #1330

@TwitchBronBron TwitchBronBron added the create-package create a temporary npm package on every commit label Jan 20, 2026
@rokucommunity-bot
Copy link
Contributor

Hey there! I just built a new temporary npm package based on 5e648aa. You can download it here or install it by running the following command:

npm install https://github.com/rokucommunity/brighterscript/releases/download/v0.0.0-packages/brighterscript-1.0.0-alpha.49-intersection-type.20260120154200.tgz

Copy link
Member

@TwitchBronBron TwitchBronBron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few small things, but overall this looks great!

export function isParamTypeFromValueReferenceType(value: any): value is ParamTypeFromValueReferenceType {
return value?.__reflection?.name === 'ParamTypeFromValueReferenceType';
}
export function isIntersectionWithDefaultDynamicReferenceType(value: any): value is IntersectionWithDefaultDynamicReferenceType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name is...a lot. 😅 It might be worth adding a comment about what this specific function actually accomplishes. I don't really understand it, even though I can read all the words in its name.


export function isInheritableType(target): target is InheritableType {
return isClassType(target) || isCallFuncableType(target) || isComplexTypeOf(target, isInheritableType);
return isClassType(target) || isInterfaceType(target) || isComponentType(target);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a bug? It used to use isComplexType but now is isComponentType. I'm not entirely sure what isInheritableType is used for, but does it allow you to do something like class Alpha extends roSGNodeGroup? (maybe all of this is fine and I'm overthinking it).

Was it actually supposed to be isCompoundType?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a bug before.

isInheritableType() is any type that can be extended with extends

}
}
if (this.checkAny(TokenKind.And, TokenKind.Or)) {
this.warnIfNotBrighterScriptMode('custom types');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better name than custom types? I know this is configurable, but feels like it would better to say something like intersection or union?

if (this.match(TokenKind.LeftCurlyBrace)) {
expr = this.inlineInterface();
} else if (this.match(TokenKind.LeftParen)) {
let left = this.previous();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this github comment be better served as an actual in-code comment?

@TwitchBronBron TwitchBronBron enabled auto-merge (squash) January 20, 2026 17:47
@rokucommunity-bot
Copy link
Contributor

Hey there! I just built a new temporary npm package based on d277935. You can download it here or install it by running the following command:

npm install https://github.com/rokucommunity/brighterscript/releases/download/v0.0.0-packages/brighterscript-1.0.0-alpha.49-intersection-type.20260120174746.tgz

Co-authored-by: Bronley Plumb <bronley@gmail.com>
@rokucommunity-bot
Copy link
Contributor

Hey there! I just built a new temporary npm package based on 92a7755. You can download it here or install it by running the following command:

npm install https://github.com/rokucommunity/brighterscript/releases/download/v0.0.0-packages/brighterscript-1.0.0-alpha.49-intersection-type.20260120180333.tgz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

create-package create a temporary npm package on every commit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants