Personally, I would like to have us support TypeScript-type interfaces where 
plain objects that have the correct properties pass the check.[1]

I have no idea how difficult this would be for SWF-compatible code, but even if 
it’s supported for JS-only code, that would be a huge production booster. 

My $0.02,
Harbs

[1]https://www.typescriptlang.org/docs/handbook/interfaces.html 
<https://www.typescriptlang.org/docs/handbook/interfaces.html>

> On Jan 7, 2019, at 6:03 AM, Alex Harui <aha...@adobe.com.INVALID> wrote:
> 
> I just fixed a bug in the compiler, and now we are getting more of these 
> implicit coercion errors because the recent Google Closure Typedefs now 
> specify interfaces as parameters to certain contructors (or maybe they always 
> did and the compiler is now getting better at catching these errors).
> 
> Code that looked like:
> 
>    var blob:Blob = new Blob([text], { type: 'text/plain' });
> 
> or
> 
>    customEvent = new window.Event(type, {bubbles: bubbles, cancelable: 
> cancelable});
> 
> now results in a compiler error because the plain objects don't implement 
> whatever interface of properties the constructor expects.  I think Google 
> Closure did this so that the properties in the plain object don't get renamed 
> by the minifier.
> 
> One solution, that Yishay tried in this commit was simply to lie to the 
> compiler and tell it that the plain object was a BlobPropertyBag.  And while 
> that is the "least amount of code" solution, I didn’t like that solution 
> because it looks funny to have lots of places in our code where a plain 
> object is coerced to a type.
> 
> So, I went and created classes that implement BlobPropertyBag and other 
> interfaces.  I didn't like adding the weight of additional class definitions 
> but the classes I did were small, just a couple of properties.  However, for 
> Event,there is a pretty big list of properties just to specify bubbles and 
> cancelable.  The compiler was not catching that plain object before, but now 
> with the fix I just made it will.  And I’m not sure it is worth adding a 
> large class with lots of properties.
> 
> So, I thought of a third idea which is a hack between what Yishay tried and 
> the interface implementations I did, which is to have a factory that returns 
> an instance of the interface, but actually returns a plain object.  As long 
> as no code actually tests that the instance implements the interface, it 
> should work.  And that would localize the coercion of a plain object to an 
> interface in relatively few known places in our code.
> 
> The pattern would be to create a top-level factory function() unless it makes 
> sense to add it to a class so for Blob it might look like:
> 
> /**
> * @royaleignorecoercion BlobPropertyBag
> */
> public function createBlobPropertyBag():BlobPropertyBag
> {
>    // return a plain object but fool the compiler into thinking it is an 
> implementation of the interface
>    return {} as BlobPropertyBag;
> }
> 
> IMO, this also future-proofs the code in case we ever run where there is 
> runtime type-checking and need to someday return a real concrete instance 
> that implements the interface.
> 
> Thoughts?
> -Alex
> 
> 
> On 12/26/18, 11:02 PM, "Yishay Weiss" <yishayj...@hotmail.com> wrote:
> 
>    Sounds good, feel free to revert.
> 
> 
> 
>    ________________________________
>    From: Alex Harui <aha...@adobe.com.INVALID>
>    Sent: Thursday, December 27, 2018 3:43:45 AM
>    To: dev@royale.apache.org; comm...@royale.apache.org
>    Subject: Re: [royale-asjs] branch develop updated: Fix implicit coercion 
> error
> 
>    I don't think we should hack it like this.  Casting a plain object to a 
> type makes the code look strange, and it might not minify correctly.  I have 
> a different fix I hope to put in shortly where we actually pass in an 
> instance of the BlogPropertyBag.
> 
>    -Alex
> 
>    On 12/26/18, 6:57 AM, "yish...@apache.org" <yish...@apache.org> wrote:
> 
>        This is an automated email from the ASF dual-hosted git repository.
> 
>        yishayw pushed a commit to branch develop
>        in repository 
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&amp;data=02%7C01%7Caharui%40adobe.com%7C00f548a683d34a9c88b508d66bc93265%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636814909228765885&amp;sdata=5DaM3aljpj1rk4FD0KBSzLWrfi9jzCOmbnAvfy2me8o%3D&amp;reserved=0
> 
> 
>        The following commit(s) were added to refs/heads/develop by this push:
>             new 2f127d4  Fix implicit coercion error
>        2f127d4 is described below
> 
>        commit 2f127d459ee807f197950e11af947c623c270369
>        Author: DESKTOP-RH4S838\Yishay <yishayj...@hotmail.com>
>        AuthorDate: Wed Dec 26 16:57:33 2018 +0200
> 
>            Fix implicit coercion error
>        ---
>         
> .../src/main/royale/org/apache/royale/storage/file/DataOutputStream.as  | 2 +-
>         .../apache/royale/storage/providers/AndroidExternalStorageProvider.as 
>   | 2 +-
>         .../royale/org/apache/royale/storage/providers/WebStorageProvider.as  
>   | 2 +-
>         3 files changed, 3 insertions(+), 3 deletions(-)
> 
>        diff --git 
> a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as
>  
> b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as
>        index cff76eb..55eab71 100644
>        --- 
> a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as
>        +++ 
> b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as
>        @@ -117,7 +117,7 @@ public class DataOutputStream extends 
> EventDispatcher implements IDataOutput
>             public function writeText(text:String):void
>             {
>                     COMPILE::JS {
>        -                   var blob:Blob = new Blob([text], { type: 
> 'text/plain' });
>        +                   var blob:Blob = new Blob([text], { type: 
> 'text/plain' } as BlobPropertyBag);
>                             _fileWriter.write(blob);
>                     }
>                     COMPILE::SWF {
>        diff --git 
> a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as
>  
> b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as
>        index ea79a5b..cf05a73 100644
>        --- 
> a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as
>        +++ 
> b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as
>        @@ -199,7 +199,7 @@ package org.apache.royale.storage.providers
>                                                                     
> _target.dispatchEvent(newEvent);
>                                                             };
> 
>        -                                                   var blob:Blob = 
> new Blob([text], { type: 'text/plain' });
>        +                                                   var blob:Blob = 
> new Blob([text], { type: 'text/plain' } as BlobPropertyBag);
>                                                             
> fileWriter.write(blob);
>                                                     }, function(e):void {
>                                                             var 
> errEvent:FileErrorEvent = new FileErrorEvent("ERROR");
>        diff --git 
> a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as
>  
> b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as
>        index 1632bfa..dd9c84c 100644
>        --- 
> a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as
>        +++ 
> b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as
>        @@ -199,7 +199,7 @@ package org.apache.royale.storage.providers
>                                                                     
> _target.dispatchEvent(newEvent);
>                                                             };
> 
>        -                                                   var blob:Blob = 
> new Blob([text], { type: 'text/plain' });
>        +                                                   var blob:Blob = 
> new Blob([text], { type: 'text/plain' } as BlobPropertyBag);
>                                                             
> fileWriter.write(blob);
>                                                     }, function(e):void {
>                                                             var 
> errEvent:FileErrorEvent = new FileErrorEvent("ERROR");
> 
> 
> 
> 
> 
> 

Reply via email to