Open Acetyld opened 1 year ago
EDIT:
To clearify my issue, the goal is to make a helper function called "add" in the entity that will handle add logic, this is the reason why i need to have a "clean" typescript type of the Task Schema.
We do have a type that isn't exported, but it's possible for you to duplicate it. It's the same type we use for the input for realm.create
. Let me know if that helps.
Lovely, altough it seems this is not working with nested relation
import { iriToId } from '@composables/utils/iriToId';
import { Department } from '@database/Department';
import { Location } from '@database/Location';
import { Team } from '@database/Team';
import { ActiveEnum } from '@database/database.enums';
import { Unmanaged } from '@database/realm.types';
import {
UserGet,
UserLocationGet,
UserManagerGet,
UserTeamGet,
} from '@features/user/user.interface';
import Realm from 'realm';
type PlainUser = Omit<
User,
| keyof Realm.Object
| 'departments'
| 'teams'
| 'managerTeams'
| 'managerDepartments'
| 'locations'
> & {
departments?: Omit<Department, keyof Realm.Object>[];
teams?: Omit<Team, keyof Realm.Object>[];
managerDepartments?: Omit<Department, keyof Realm.Object>[];
managerTeams?: Omit<Team, keyof Realm.Object>[];
locations?: Omit<Location, keyof Realm.Object>[];
};
export class User extends Realm.Object<User, 'id'> {
id!: number;
'@id'?: string;
fullName?: string;
avatar?: string;
username?: string;
email?: string;
roles?: string[];
active?: ActiveEnum;
createdAt?: Date;
updatedAt?: Date;
deletedAt?: Date;
departments?: Realm.List<Department>;
teams?: Realm.List<Team>;
managerDepartments?: Realm.List<Department>;
managerTeams?: Realm.List<Team>;
locations?: Realm.List<Location>;
__isDeleted?: boolean;
__isSynced?: boolean;
static schema = {
name: 'User',
primaryKey: 'id',
properties: {
id: 'int',
'@id': 'string?',
fullName: { type: 'string?', indexed: true },
email: 'string?',
avatar: 'string?',
username: 'string?',
roles: 'string?[]',
active: 'int?',
createdAt: 'date?',
updatedAt: 'date?',
deletedAt: 'date?',
departments: { type: 'Department[]', default: [] },
teams: { type: 'Team[]', default: [] },
managerDepartments: { type: 'Department[]', default: [] },
managerTeams: { type: 'Team[]', default: [] },
locations: { type: 'Location[]' },
__isDeleted: { type: 'bool', default: false, indexed: true },
__isSynced: { type: 'bool', default: false, indexed: true },
},
};
static add(realm: Realm, userResponse: UserGet): Unmanaged<User> {
const user: Unmanaged<User> = {
id: userResponse.id,
'@id': userResponse['@id'],
fullName: userResponse.fullName,
email: userResponse.email,
username: userResponse.username,
roles: userResponse.roles || [],
active: userResponse.active,
createdAt: new Date(userResponse.createdAt),
updatedAt: new Date(userResponse.updatedAt),
deletedAt: userResponse.deletedAt
? new Date(userResponse.deletedAt)
: undefined,
avatar: userResponse.avatar || undefined,
__isSynced: true,
};
user.departments = mapUserRelation(realm, userResponse.departments || []);
// user.managerDepartments = mapUserRelation(
// realm,
// userResponse.managerDepartments || [],
// );
// user.teams = mapUserRelation(realm, userResponse.teams || []);
// user.managerTeams = mapUserRelation(realm, userResponse.managerTeams || []);
// user.locations = mapUserRelation(realm, userResponse.locations || []);
return user;
}
}
const mapUserRelation = (
realm: Realm,
items: UserManagerGet[] | UserTeamGet[] | UserLocationGet[],
) => {
return items.map(item => {
const iri = item['@id'];
const id = iriToId(iri);
const entity = realm.objectForPrimaryKey(Department, id);
if (!entity) {
return { id };
}
return entity;
});
};
The user.deparments still gives:
TS2740: Type
((Department & Object<Department, never>) | { id: number; })[]
is missing the following properties from type List
Extending Realm.Object is what causes this. I hate it too, it makes it a PITA to work with the plain objects or copy one object into another collection (and keep types sane). What I do instead is keep a bare interface and a separate schema:
export interface User {
id!: number
username?: string
email?: string
departments: Array<Department>
// etc.
}
export const UserSchema = {
name: "User",
properties: {
id: "int",
username: "string?",
email: "string?",
departments: "Department[]"
// etc.
}
}
That allows you to use plain old typescript objects for your models. You pass UserSchema.name
instead of the class when doing your queries and the queries come back with the type of User & Realm.Object
. Doing a .toJSON
on those will give you the type without the Realm.Object
, but may require casting as User
and is certainly inefficient if you're doing it on a set of data instead of a single object.
I hope they're able to get rid of the requirement to extend Realm.Object in Realm 12 as it certainly adds complications in my project.
able to get rid of the requirement to extend Realm.Object in Realm 12
We don't intent to change it in v12. It is a complete rewrite of the code base, and we don't want to change behavior AND code base at the same time (so we can avoid going insane). But we plan to change it in v13.
Yhea the method provided above is a bit hard to test, bcs no types are exported, i put somet ime into copying from remote, and trying to get it to work, without success so i stuk to me:
type PlainMean = Omit<
Mean,
keyof Realm.Object | 'space' | 'object' | 'location'
> & {
space?: Omit<Space, keyof Realm.Object>;
object?: Omit<Objects, keyof Realm.Object>;
location?: Omit<Location, keyof Realm.Object>;
};
able to get rid of the requirement to extend Realm.Object in Realm 12
We don't intent to change it in v12. It is a complete rewrite of the code base, and we don't want to change behavior AND code base at the same time (so we can avoid going insane). But we plan to change it in v13.
Is there already any upcoming update above above?
Hi! I faced the same issue! Maybe someone can advise a library (if it exists), one like OpenApi that generates types from schemas
How frequently does the bug occur?
Always
Description
Lets say i do this:
And my entity is
If i want some good typescript auto complete i need to prefix the type with :Task but this is causing another issue, i wants to me implement stuff like: linkingObjects, keys, toJson, entries, isValid, etc...
In another place i manged to find a work around
This will bassicly bypass the need of the realm.object stuff. I also tried using the babel transformer but as discussed in earlier of my post this caused more good then harm.
So am i doing something wrong? I just want good auto complete on realm.write, if i have a api response with TaskReponseItem and i do a ream.write i want to clearly know what i am doing wrong if fields dont match types.
Stacktrace & log output
No response
Can you reproduce the bug?
Always
Reproduction Steps
No response
Version
^11.10.1
What services are you using?
Local Database only
Are you using encryption?
No
Platform OS and version(s)
Newest expo 49
Build environment
Which debugger for React Native: ..
Cocoapods version
No response