Dependencies
Codable classes and custom types can depend on other codable classes or types.
Thanks to dependencies option, each type or class can declare its own dependencies.
This allows you to write code that is more modular and self-contained, instead of having some central place where you collect all of custom types (which you can still do, if you want to).
Basic Usage
When your class contains instances of other codable classes, you can specify them as dependencies:
@codableClass("Bar")
class Bar {
@codable()
bar: string = "bar";
}
// If we are encoding Foo, Bar will also be encoded.
@codableClass("Foo", { dependencies: [Bar] })
class Foo {
@codable()
bar = new Bar();
}
const coder = new Coder([Foo]); // Only need to register Foo!
const foo = new Foo();
const encoded = coder.encode(foo);
// { $$Foo: [{ bar: { $$Bar: [{ bar: "bar" }] } }] }
const decoded = coder.decode<Foo>(encoded);
// decoded.bar is properly typed as Bar instanceAutomatic Discovery
Now, you only need to register the root class, and all dependencies will be automatically discovered.
// Without dependencies - you'd need to register both classes
const coder = new Coder([Foo, Bar]); // Before
// With dependencies - automatic discovery
const coder = new Coder([Foo]); // NowLazy Dependencies (Thunks)
Below, we have two classes that depend on each other.
You can use function thunks to defer the dependency resolution:
// Lazy evaluation
@codableClass("User", { dependencies: () => [Post] })
class User {
@codable()
name: string;
@codable()
posts: Post[] = [];
constructor(data: Memberwise<User, "name">) {
this.name = data.name;
}
}
@codableClass("Post", { dependencies: () => [User] })
class Post {
@codable()
title: string;
@codable()
author: User;
constructor(data: Pick<Post, "title" | "author">) {
this.title = data.title;
this.author = data.author;
}
}
const coder = new Coder([Post]); // User is discovered lazilyComplex Dependency Graphs
Dependencies work seamlessly with complex object hierarchies:
@codableClass("Comment", { dependencies: () => [User] })
class Comment {
@codable()
text: string;
@codable()
author: User;
constructor(data: Memberwise<Comment, "text" | "author">) {
this.text = data.text;
this.author = data.author;
}
}
@codableClass("Post", { dependencies: () => [User, Comment] })
class Post {
@codable()
title: string;
@codable()
content: string;
@codable()
author: User;
@codable()
comments: Comment[] = [];
constructor(data: Memberwise<Post, "title" | "content" | "author">) {
this.title = data.title;
this.content = data.content;
this.author = data.author;
}
}
@codableClass("Blog", { dependencies: () => [Post] })
class Blog {
@codable()
name: string;
@codable()
posts: Post[] = [];
constructor(data: Memberwise<Blog, "name">) {
this.name = data.name;
}
}
// Only need to register the root class
const coder = new Coder([Blog]);
// User, Comment, and Post are all automatically discoveredLast updated on