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 > >>>> > >>>> > >> > >> > >
