Async creation function requires the usage of `new this()` not `new ClassName()`
CMCDragonkai opened this issue · comments
Describe the bug
When using CreateDestroy
or CreateDestroyStartStop
, it is necessary for the async creation function to use new this()
.
If you use new ClassName()
then it will fail due to the constructor not referring to the decorated class constructor.
This only seems to occur with SWC, TSC works fine.
I have a memory of having reported this already upstream to SWC, but evidently it's not fixed and I cannot find the issue I reported or saw...
To Reproduce
- Create a prototype script with
class X
withCreateDestroyStartStop
and a@ready
method - Run it with
npm run ts-node -- ./test.ts
- See the result between swc enabled or disabled
- Change to
new this
and it should work!
Expected behavior
The SWC should behave the same as TSC.
Here is the example that demonstrates the problem.
import { CreateDestroyStartStop, ready } from '@matrixai/async-init/dist/CreateDestroyStartStop';
interface X extends CreateDestroyStartStop {}
@CreateDestroyStartStop()
class X {
static async createXWorks() {
return new this();
}
static async createXFails() {
return new X();
}
async start() {}
async stop() {}
async destroy() {}
@ready()
async thing() {}
}
async function mainWorks () {
const x = await X.createXWorks();
await x.start()
await x.thing();
await x.stop();
await x.destroy();
}
async function mainFails () {
const x = await X.createXFails();
await x.start()
await x.thing();
await x.stop();
await x.destroy();
}
// void mainWorks();
void mainFails();
mainFails fails with the following error.
[nix-shell:~/matixWorkspace/gitRepos/js-db]$ npm run ts-node -- test.ts
> @matrixai/db@5.1.0 ts-node
> ts-node "test.ts"
TypeError: Cannot read properties of undefined (reading 'isLocked')
at X.thing (/home/faulkes/matixWorkspace/gitRepos/js-db/node_modules/@matrixai/async-init/src/CreateDestroyStartStop.ts:189:30)
at mainFails (/home/faulkes/matixWorkspace/gitRepos/js-db/test.ts:44:11)
The decorators here are setting up some state in the constructor. Relevant to this problem it's creating mutex lock and storing it in a property using a symbol as the key.
const initLock = Symbol('initLock');
// Decorator is adding this to the class.
readonly [initLock]: RWLockWriter;
// The @ready decorator is trying to access it.
this[initLock].isLocked('write')
Created upstream issue at swc-project/swc#7426
The upstream wants a playground example showing the problem. I'm going to create one and update the issue.
Note that this is not a bug of this library. Users should just make sure to use new this()
in their creation functions.
However in this project, we can change all of our tests and examples to use new this()
.