I would like to be able to refer to Realm objects defined through an ObjectSchema with a concrete type rather than any in TypeScript.
Be able to use explicit types for queries and Realm objects instead of having to use any.
At the moment if I make a query, TypeScript will infer the type to be Results<{}> and hence I cannot access the properties of the actual ObjectSchema.
Create a model using an ObjectSchema and query objects of that type.
This is one of my ObjectSchema definitions:
const VideoSchema: Realm.ObjectSchema = {
name: 'Video',
primaryKey: 'youtubeID',
properties: {
youtubeID: 'string',
title: 'string',
filePath: 'string?',
thumbnailPath: 'string?',
uploadDate: 'date'
}
};
This is how I query the objects from Realm and try to access their properties:
const videos = realm.objects(VideoSchema);
for (let i=0;i<videos.length;i++){
videos[i].title = "a"; //Error 2339: Property 'title' does not exist on type '{}'
}
The error:
Error 2339: Property 'title' does not exist on type '{}'
The results are the same if I change my query to const videos=realm.objects('Video');.
The only possible solution I have found so far was to explicitly cast the Results instance to any by const videos:any = realm.objects(VideoSchema).
It seems to me that the use of classes would solve my issue, however, according to the docs, defining models via classes is not available in Node yet.
I have just started using TypeScript, so I might be missing something, but I'd be glad if someone could shed some light on this issue for me.
You will need to define actual types for the objects in your schema so that Typescript know which types to return and expect.
So to update your code sample, you could do something like this:
class Video {
public static schema: Realm.ObjectSchema = {
name: 'Video',
primaryKey: 'youtubeID',
properties: {
youtubeID: 'string',
title: 'string',
filePath: 'string?',
thumbnailPath: 'string?',
uploadDate: 'date'
}
}
public youtubeID: string;
public title: string;
public filePath?: string | null;
public thumbnailPath?: string | null;
public uploadDate: Date;
}
const videos = realm.objects<Video>(Video.schema.name);
for (let i=0;i<videos.length;i++){
videos[i].title = "a";
}
@astigsen thanks for your help, I knew I missed something! However, using your code I run into a new issue - on each property defined in my class, I receive the following error:
Error 2564: Property 'youtubeID' has no initializer and is not definitely assigned in the constructor
Does this mean I should create an initializer for all my Realm model classes even though I only instantiate them through realm.create? Or does realm.create actually call the initializer that I would create under the hood?
What is your TSC options? I can transpile and run the following code:
import * as Realm from "realm";
class Video {
public static schema: Realm.ObjectSchema = {
name: 'Video',
primaryKey: 'youtubeID',
properties: {
youtubeID: 'string',
title: 'string',
filePath: 'string?',
thumbnailPath: 'string?',
uploadDate: 'date'
}
}
public youtubeID: string;
public title: string;
public filePath?: string | null;
public thumbnailPath?: string | null;
public uploadDate: Date;
constructor(youtubeID: string, title: string, uploadDate: Date) {
this.youtubeID = youtubeID;
this.title = title;
this.uploadDate = uploadDate;
}
};
let realm = new Realm({schema: [Video.schema]});
realm.write(() => {
let video = new Video('foo', 'bar', new Date());
realm.create(Video.schema.name, video);
});
console.log('Done', realm.objects(Video.schema.name));
realm.close();
You probably have the strictPropertyInitialization option enabled in your compiler options. That will require you to to add initializers for all properties. Realm does not require it if you initialize the object with Realm.create() (but add the type hint, as in Realm.create<Video>() to help the compiler).
Thanks for both of you, I had the strict flag enabled, which in turn enabled the strictPropertyInitialization. I disabled the latter flag manually, since I'm only creating Realm object using Realm.create() and now everything's working fine.
Check this out: https://github.com/IgorP120/realm-typescript-extensions
Most helpful comment
What is your TSC options? I can transpile and run the following code: