I found a relatively easy/safe solution is to create a new abstract with the fields I want to have type safety on. It ends up looking like this:
@:access(GenericStore)
abstract Customer(GenericStore) {
public var firstName(get,set):String;
public var lastName(get,set):String;
function get_firstName() {
return Reflect.field(this.fields, "firstName");
}
function set_firstName(val:String) {
Reflect.setField(this.fields, "firstName", val);
return val;
}
function get_lastName() {
return Reflect.field(this.fields, "lastName");
}
function set_lastName(val:String) {
Reflect.setField(this.fields, "lastName", val);
return val;
}
}
Now I can do var castedCustomer = cast(customer, Customer);
and it works great. The class could be built by a macro that reads in typedefs. I was hoping to see a way to layer a typedef on top of the abstract, but this works too.