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 {ConstructorOf} from "../utils";
|
||||
import {ConstructorOf, Modify} from "../utils";
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
@ -2,3 +2,8 @@
|
|||
* Type definition of a class constructor.
|
||||
*/
|
||||
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", () => {
|
||||
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", () => {
|
||||
const article = getTestArticle();
|
||||
const newModel = Article.model.model(article);
|
||||
|
|
Loading…
Add table
Reference in a new issue