tink_sql
tink_sql copied to clipboard
Typing problems when using `final`
typedef User = {
@:primary @:autoIncrement final id:Id<User>;
@:unique final username:VarChar<255>;
final password:VarChar<64>;
final salt:VarChar<32>;
final displayName:VarChar<255>;
final roles:Int;
}
...
typedef UserVo = {
var id(default, never):Int;
var username(default, never):String;
var displayName(default, never):String;
var isAdmin(default, never):Bool;
var isSuperUser(default, never):Bool;
}
...
public function list():Promise<Array<UserVo>>
return db.User.all()
.next(all -> all.map(parseUser));
static function parseUser(u:User):UserVo
return {
id: u.id,
username: u.username,
displayName: u.displayName,
isAdmin: u.roles & UserRole.ADMIN != 0,
isSuperUser: u.roles & UserRole.SUPERUSER != 0
};
The following doesn't compile using the latest haxe nightly, complaining about:
src/server/api/UsersApi.hx:9: characters 31-34 : error: Cannot unify final and non-final fields
src/server/api/UsersApi.hx:9: characters 31-34 : have: { displayName: Dynamic }
src/server/api/UsersApi.hx:9: characters 31-34 : want: { displayName: Dynamic }
src/server/api/UsersApi.hx:9: characters 31-34 : For function argument 'u'
If I remove the finals, everything works.
If I inline the code from parseUser
into the .next()
, everything works.
The problem happens when trying to type the result of .all()
(or .first()
) as db.User
. But in theory it should be db.User
, why isn't it?
I suspect the row type for the result set does not have final fields, mostly because https://github.com/haxetink/tink_macro/issues/17
Also having this problem, and so does @kevinresol as he confirmed on gitter.
Is it really because of the unimplemented default:
linked by @back2dos last year? Issue has been fixed though, but I'm putting macro Sisyphus content here in order to try to attract interest on this issue:
class Sisyphus {
static function nullable(complexType : ComplexType) : ComplexType return macro : Null<$complexType>;
static function toField(cf : ClassField) : Field return {
function varAccessToString(va : VarAccess, getOrSet : String) : String return {
switch (va) {
case AccNormal: "default";
case AccNo: "null";
case AccNever: "never";
case AccResolve: throw "Invalid TAnonymous";
case AccCall: getOrSet;
case AccInline: "default";
case AccRequire(_, _): "default";
default: throw "not implemented";
}
}
Seeming to suggests in order to fix this issue toField(String):String
could not be used anymore?