Yeah, I think that a "this" type, similar to TypeScript's, could be useful
here. I've always liked that feature.

I think that adding a "this" type should be relatively straightforward. At
least compared to the effort of adding function type expressions. The
tricky part is figuring out which class should be resolved based on the
context where the method is called or the property is accessed. My initial
thought would be a couple of months of development and testing.

We probably shouldn't delay a release to add it, though.

--
Josh Tynjala
Bowler Hat LLC
https://bowlerhat.dev/


On Tue, Jan 27, 2026 at 2:19 AM Harbs <[email protected]> wrote:

> For case 1, Typescript has a feature which would work nicely. You can use
> “this” as a type declaration and it is resolved to the currently used type:
>
> https://www.typescriptlang.org/docs/handbook/2/classes.html#this-types
>
> How difficult would it be to copy that feature for ActionScript?
>
> Harbs
>
> > On Jan 27, 2026, at 10:50 AM, Harbs <[email protected]> wrote:
> >
> > I wanted to discuss this in a dedicated discussion because the details
> will get involved:
> >
> >> Hmm. I’m not sure it’s working as I’d expect.
> >>
> >> In Core, there’s TaskTest which has this:
> >>
> >>
> >>                      [Test(async,timeout="50")]
> >>                      public function testPromiseToTask():void
> >>                      {
> >>                              var resolvePromise:Promise = new
> Promise(function(resolve:Function, reject:Function):void{
> >>                                      resolve("resolved");
> >>                              });
> >>                              var resolvedTask:PromiseTask =
> promiseToTask(resolvePromise);
> >>
> resolvedTask.done(function(task:PromiseTask):void{
> >>                                      assertEquals(task.result,
> "resolved");
> >>                              });
> >>                              resolvedTask.run();
> >>                      }
> >>
> >> The compiler is now complaining:
> >>
> >> Implicit coercion of a value of type
> >> (task:org.apache.royale.utils.async.PromiseTask)=>void to an unrelated
> type
> >> (task:org.apache.royale.utils.async.IAsyncTask)=>void.(1067)
> >>
> >> A PromiseTask extends AsyncTask which implements IAsyncTask.
> >>
> >> I think that should be allowed.
> >
> >
> > I think I understand why it’s working like that, but we want a feature
> which is more useful than annoying.
> >
> > A function has two parts: 1. The arguments 2. the return value.
> >
> > When passing a function into a client, the client is a consumer of the
> return value, but a “producer” of the arguments. Since the function is
> expecting a more specific type than the “client” is producing, that might
> cause a type mismatch. My assumption is that this error is specific to
> parameters and not return types.
> >
> > Now, while this behavior makes sense from a type-safety perspective, I’m
> not sure how useful it will be practically. The typescript type system
> often tends to be annoying enough that people often just revert to using
> “any”. I’d like to find the right balance of type safety and usefulness.
> With that in mind, I’d like to lay out where I see this feature being used
> and useful and figure out if we have those bases covered. I’m going to
> discuss specific cases because that’s easier for me than discussion the
> abstract.
> >
> > 1. AsyncTasks take callbacks which are called when the task is done. The
> callbacks are always called by passing in the task in the task instance.
> The methods (done and exec) are defined in the base class and we don’t want
> to redefine those for every subclass. The callback is handled differently
> for each task, so the specific type is important in the callback definition.
> >
> > 2. Event callbacks. All EventDispatchers dispatch events which are of
> type Event. Specific classes will dispatch more specific events. It’s
> useful to make sure that event listeners are the right shape. It would be
> even more useful to know which events should be handled for specific event
> listeners.
> >
> > 3. Runtime swappable utility functions which calculate some value. (One
> example of this is labelFunction.) The return type of these functions
> should be well defined. The arguments should be pretty well defined as well.
> >
> > The first case is not working very well with the current implementation.
> By definition, the type supplied to the callback will always be the type of
> the specific instance of AsyncTask. Ideally we should have a “this” type we
> can declare which would be inferred from the current instance.
> >
> > The second case is a more difficult problem. The specific event type
> dispatched cannot be known because a single class can dispatch different
> event types depending on the specific event. I’m not sure how it’s possible
> to even decorate all the options. Maybe if we had union types we could do
> something. For this case it feels like we need some way to declare a type
> in the function parameter that’s explicitly telling the compiler “I know
> this type is more specific than what’s expected, but that’s OK”. I do think
> that it should have an error if it doesn’t match the less specific
> definition though.
> >
> > For the third case, I think the implementation as it is, is fine.
> >
> > Thoughts?
> > Harbs
>
>

Reply via email to