Concern Class
This chapter shows how to create a new concern class.
Inherit from AbstractConcern
To create a new concern class, you can inherit from the AbstractConcern
class.
import { AbstractConcern } from "@aedart/support/concerns";
class MyConcern extends AbstractConcern {
get message() { /* ...not shown */ }
set message(message) { /* ...not shown */ }
foo() { /* ...not shown */ }
[MY_SYMBOL]() { /* ...not shown */ }
}
By default, all the public properties and methods (all property keys) are made available for "aliasing" into a target class. To configure which members should be made available for aliasing, see Customise "alias" members.
Private Members
Note
Private methods and properties are NEVER "aliased" into a target class.
Static Members
Note
Static methods and properties are NOT "aliased" into target class.
At the moment, such a feature is not supported by the concerns' mechanism.This may become available in the future, but presently you SHOULD NOT rely on static members becoming available for aliasing.
Transpilers
Caution
Some transpilers, like Babel and TypeScript, automatically move property declarations into the class' constructor
. For instance:
class A {
foo = 'bar';
}
becomes like the following, after it has been transpiled:
class A {
constructor() {
this.foo = 'bar';
}
}
When this happens, properties cannot be "aliased". The concern mechanisms relies on the class' prototype for reading what properties are available. To overcome such an issue, you can use getters and setters instead.
class A {
#foo = 'bar';
get foo() {
return this.#foo
}
set foo(v) {
this.#foo = v;
}
}
Customise "alias" members
If you wish to customise what properties and methods should be available for aliasing when used by a target class, overwrite the static PROVIDES
method.
import { AbstractConcern, PROVIDES } from "@aedart/support/concerns";
class MyConcern extends AbstractConcern {
get message() { /* ...not shown */ }
set message(message) { /* ...not shown */ }
foo() { /* ...not shown */ }
[MY_SYMBOL]() { /* ...not shown */ }
static [PROVIDES]() {
// Make "message" and "foo" available for aliasing...
return [
'message',
'foo'
];
}
}
warning
Even if you do customise what properties and methods are available for aliasing, the returned property keys of the PROVIDES
method can be overruled, via conflict resolution!
If you truly wish to prevent certain properties or methods from being aliased into a target class, then you should declare them as private.
Concern Owner instance
The concernOwner
property gives you direct access to the target class instance, in your concern. This allows you to create interaction between the target instance and your concern, which can be usefully in any number of situations. For instance, you can use the concernOwner
to create a fluent design of your utilities.
class ConcernsPeople extends AbstractConcern {
with(value) {
// ...not shown here...
return this.concernOwner;
}
}
@use(ConcernsPeople)
class Invitation {
invite() { /* ...not shown here... */ }
}
const party = new Invitation();
party
.with('Anna')
.with('Anders')
.with('Ulla')
.with('Jimmy')
.invite();
Constructor
Should you require initialisation logic, then you can overwrite the constructor
in your concern class. A concern's constructor is only given the target class instance as argument.
See booting for additional information.
class Recording extends AbstractConcern {
constructor(owner) {
super(owner);
// ...perform your initialisation here...
}
}