Add extend function to easily extend an inherited model.
All checks were successful
/ test (push) Successful in 40s
All checks were successful
/ test (push) Successful in 40s
This commit is contained in:
parent
75b7b35dd6
commit
ecd8852afa
3 changed files with 58 additions and 1 deletions
|
@ -1,5 +1,5 @@
|
||||||
import {Definition, UnknownDefinition} from "./property-definition";
|
import {Definition, UnknownDefinition} from "./property-definition";
|
||||||
import {ConstructorOf} from "../utils";
|
import {ConstructorOf, Modify} from "../utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A model shape.
|
* A model shape.
|
||||||
|
@ -524,6 +524,32 @@ export function defineModel<T extends object, Shape extends ModelShape<T>, Ident
|
||||||
return new ModelManager<T, Shape, Identifier>(definition);
|
return new ModelManager<T, Shape, Identifier>(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a new model, extending an existing one.
|
||||||
|
* @param extendedModel The extended model manager instance.
|
||||||
|
* @param definition The extension of the model definition object.
|
||||||
|
*/
|
||||||
|
export function extend<
|
||||||
|
ExtT extends object, ExtShape extends ModelShape<ExtT>, ExtIdentifier extends IdentifierDefinition<ExtT, ExtShape>,
|
||||||
|
T extends ExtT, Shape extends ModelShape<T>, Identifier extends IdentifierDefinition<T, Shape>,
|
||||||
|
ResIdentifier extends IdentifierDefinition<T, ResShape>, ResShape extends ModelShape<T> = Modify<ExtShape, Shape>
|
||||||
|
>(
|
||||||
|
extendedModel: ModelManager<ExtT, ExtShape, ExtIdentifier>,
|
||||||
|
definition: ModelDefinition<T, Shape, Identifier>,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const { properties: extendedProperties, ...overridableDefinition } = extendedModel.definition;
|
||||||
|
const { properties: propertiesExtension, ...definitionExtension } = definition;
|
||||||
|
return new ModelManager({
|
||||||
|
...overridableDefinition,
|
||||||
|
...definitionExtension,
|
||||||
|
properties: {
|
||||||
|
...extendedProperties,
|
||||||
|
...propertiesExtension,
|
||||||
|
},
|
||||||
|
}) as unknown as ModelManager<T, ResShape, ResIdentifier>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic model manager for a provided model type, to use in circular dependencies.
|
* A generic model manager for a provided model type, to use in circular dependencies.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,3 +2,8 @@
|
||||||
* Type definition of a class constructor.
|
* Type definition of a class constructor.
|
||||||
*/
|
*/
|
||||||
export type ConstructorOf<T extends object> = { new(): T; };
|
export type ConstructorOf<T extends object> = { new(): T; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type definition of an original object overridden by another.
|
||||||
|
*/
|
||||||
|
export type Modify<Original, Override> = Omit<Original, keyof Override> & Override;
|
||||||
|
|
|
@ -106,6 +106,32 @@ function getTestArticle(): Article
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("model", () => {
|
describe("model", () => {
|
||||||
|
it("defines a new model, extending an existing one", () => {
|
||||||
|
class ExtendedAccount extends Account
|
||||||
|
{
|
||||||
|
static extendedModel = s.extend(Account.model, {
|
||||||
|
Class: ExtendedAccount,
|
||||||
|
properties: {
|
||||||
|
extendedProperty: s.property.string(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
extendedProperty: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(ExtendedAccount.extendedModel.definition).toEqual({
|
||||||
|
Class: ExtendedAccount,
|
||||||
|
identifier: "id",
|
||||||
|
properties: {
|
||||||
|
id: s.property.numeric(),
|
||||||
|
createdAt: s.property.date(),
|
||||||
|
name: s.property.string(),
|
||||||
|
email: s.property.string(),
|
||||||
|
active: s.property.boolean(),
|
||||||
|
extendedProperty: s.property.string(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
it("initializes a new model", () => {
|
it("initializes a new model", () => {
|
||||||
const article = getTestArticle();
|
const article = getTestArticle();
|
||||||
const newModel = Article.model.model(article);
|
const newModel = Article.model.model(article);
|
||||||
|
|
Loading…
Add table
Reference in a new issue