Adding new fields to a typedef without compiler error?

Is it possible to create additional variables in a structure defined by a typedef?
Here’s an example of the issue that I’ve come across:

typedef MissionData = {
  var state:MissionState;
  var progress:Int;
}

class Mission {
  public var data:MissionData;
  public function new() {
    data = {state:MissionState.INACTIVE, progress: 0};
  }
  ...
  public function pick_up_a_key() {
    data.progress++;
    data.found_key = true; // results in error: MissionData has no field found_key
  }
}

My MissionData typedef defines 2 common variables that are needed for all Missions, but some missions have unique variables that need to be saved.
I could add var ?found_key:Bool to the typedef, but there are many other missions and many other optional variables that I would need to add, over 100.
Or I could create a new typedef inheriting MissionData for each mission, but this would also lead to considerable code bloat, unless automated with a macro.
Or I could add an extra field ‘var ?custom:Dynamic’, initialize it as an empty structure, and save all my extra variables in this.
…Or can I just tell Haxe to ignore the compile error?

Hej,

Something like that may help : Try Haxe !
It ensure mandatory fields on construct with their types but after that because of Dynamic it loose the type constraint :confused:
NOTE : It won’t compile on Hashlink I don’t know why

1 Like

I think this problem is a design challenge rather than a compiler question. You can always use dynamic or a separate hashmap if you want a bag of extra properties. I.e. add an extra field extraData: Dynamic.

This approach makes the most sense, I’m not sure what code bloat you mean however, you just have

typedef Mission1 = MissionData & {
    var found_key: Bool;
}

You could use a type param if you don’t want to define a new typedef

typedef MissionData<ExtraType> = {
  var state:MissionState;
  var progress:Int;
  var extra: ExtraType;
}

var data: MissionData <{ found_key: Bool }>

I dug a bit because I also needed this kind of stuff for my dev in the past and I was surprised that we can use macro function for @:op() overloading :slight_smile:
So now it’s a kind of strong typed partial typedef where you can add dynamically properties even with T constraint : Try Haxe !

Personally, I would just go with one of these. Probably the second one. I would not consider it bloat. I’d rather have the compiler tell me about mistakes in my code.

This is probably your best option for least code required, but at the higher risk of typos slowing you down.

1 Like