Yes, it is reversed for return types.

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


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

> > A similar error may be reported if the return types are not compatible.
>
> Shouldn’t the logic be reversed for the return types?
>
> If the client is expecting A, the fact that the function returns a
> subclass B shouldn’t be an issue.
>
> > On Jan 27, 2026, at 8:04 PM, Josh Tynjala <[email protected]>
> wrote:
> >
> >> Is my assumption about this error being specific to function arguments
> > correct?
> >
> > A similar error may be reported if the return types are not compatible.
> >
> >> Do you have any thoughts on implicit “as” for function arguments to make
> > this more useful for things like event handlers?
> >
> > I'd like to think on it for a bit.
> >
> > --
> > Josh Tynjala
> > Bowler Hat LLC
> > https://bowlerhat.dev/
> >
> >
> > On Tue, Jan 27, 2026 at 9:47 AM Harbs <[email protected]> wrote:
> >
> >> Agreed. The feature is useful even for just case 3. I will try to adopt
> it
> >> for those cases and see how that goes.
> >>
> >> Is my assumption about this error being specific to function arguments
> >> correct?
> >>
> >> Do you have any thoughts on implicit “as” for function arguments to make
> >> this more useful for things like event handlers?
> >>
> >> Maybe something like:
> >> addEventListener(“change”,function(event:!ValueEvent):void{}) The
> >> exclamation mark (or something else) can tell the compiler that a
> subclass
> >> is acceptable.
> >>
> >>> On Jan 27, 2026, at 7:37 PM, Josh Tynjala <[email protected]>
> >> wrote:
> >>>
> >>> 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