COMMUNITY

Is it a bug?

Hej !

This example compiles fine, Is it a bug please ?
I think it should throw that this has an extra field foo

class Test {
  static function main() {
    function getH(){
      return [ for( i in 0...10 ) i=>{ v : i } ];
    }
    var a = [];
    for( i=>o in getH() ){
      a.push( { a : i, b : o, foo : null } );
    }
    $type( a );     // <-- Array<{ foo : Unknown<0>, b : { v : Int }, a : Int }>
    parseA( a );
  }
  static function parseA( a : Array<{ a : Int, ?b : { v : Int }, ?c : { t : String } }> ){}
}

Looks fine to me, I think there’s been work recently on making it not throw that error (since 4.2 ish)

Thanks for reply George,

So why this one throws the error please ?

class Test {
  static function main() {
    function getH(){
      return [ for( i in 0...10 ) i=>{ v : i } ];
    }
    var a = [];
    for( i=>o in getH() ){
      a.push( { a : i, b : o, foo : null } );
    }
    $type( a );
    parseA( a );
    parseA( [ { a : 1, b : { v : 1 }, foo : null } ] ); // <-- Error "extra field foo..."
  }
  static function parseA( a : Array<{ a : Int, ?b : { v : Int }, ?c : { t : String } }> ){}
}

Good spot, and when you make it a variable it doesn’t throw an error

var b = [ { a : 1, b : { v : 1 }, foo : null }];
parseA( b ); // no error

I think this is deliberate behavior, where if it’s a direct expression it errors, to help detect typos

But never been a fan of the inconsistency personally because of the confusion it creates

There’s a big old discussion here

1 Like

Thanks for simplifying the example, so this is not considered as a bug is I understand well, right ?

class Test {
  static function main() {
    var a = [ { v : 1, foo : null }];
    $type( a );
    parseA( a ); // no error
    //parseA( [ { a : 1, foo : null } ] ); // error
  }
  static function parseA( a : Array<{ v : Int }> ){}
}

And this one throws both errors :

class Test {
  static function main() {
    var v = { a : 1, foo : null };
    $type( v );
    parseV( v ); // error
    //parseA( { a : 1, foo : null } ); // error
  }
  static function parseA( v : { a : Int } ){}
}

Second one has typo parseV, which doesn’t error when you correct it

Which maps to the behavior as I understand it - the compiler is stricter if you use the expression directly and allows structural sub typing if it’s a variable

You’re right sorry, have wrote to quickly…
So at the end this one is the simpliest example and it’s ok…Ok :frowning:

class Test {
  static function main() {
    var v = { a : 1, foo : null };
    $type( v );
    parseV( v ); // no error
    //parseV( { a : 1, foo : null } ); // error
  }
  static function parseV( v : { a : Int } ){}
}

I think using typedef’s are likely safer?

1 Like

Yes you’re right, thanks for the hint !
Maybe compiler could some kind do a temporary typedef to ensure this kind of things ?