menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

TypeScript

A place to talk about TypeScript.

Channels
Team

Problem assigning properties with async code in class initializer

March 25, 2021 at 6:43am

Problem assigning properties with async code in class initializer

March 25, 2021 at 6:43am

What I have

I have one class that executes in Its constructor only async code and other code that depends on async code result. According to some StackOverflow answers, to execute asynchronous code in class constructor I can follow one of two paths, run async code on init method or use an static async factory function.
Whichever path I take, I have to create some class properties with async operation result.

What I've tried:

1. Create static async factory function

class MyClass {
private constructor() {
// No async calls here
}
static async create (
someParameter,
anotherParameter,
) {
const myClass = new Myclass();
const foo = await something(someParameter);
// Create some class properties with async operation result
myClass.property = foo;
return myClass;
}
}
// with this I can create a class with
const myClass = await MyClass.create(x,y)
The problem with this aproach is, if I tried to access to class properties created with async result like so: myClass.property, TS compiler thrown an error TS2339: Property 'property' does not exist on type 'MyClass'. The other thing is ESLint thrown an error because of empty constructor: ESLint: Unexpected empty constructor..

2. Use init method

With this approach, I can access to this an asign properties to it:
class MyClass {
property: SomeType;
constructor() {
// No async calls here
}
async init (
someParameter,
anotherParameter,
) {
const foo = await something(someParameter);
// Create some class properties with async operation result
this.property = foo;
return this;
}
}
// with this I can create a class with
const currentClass = new MyClass();
const myClass = currentClass.init(x, y);
With this approach, I create a filed to avoid the problem TS2339: Property 'property' does not exist on type 'MyClass'. but some new problems are thrown: TS2564: Property 'property' has no initializer and is not definitely assigned in the constructor. and the constructor empty problem continues.

The problem

With the above, I don't know what its the correct way to run asynchronous code when initialising a class and create properties with that async result. if I leave the constructor empty I get the above mentioned errors and the same happens if I create fields without a constructor.
The idea I have in my head is to hide some complexity when creating a class where only some configuration values are needed which can be passed as arguments to the constructor, perform the asynchronous operations and with Its result create properties which the final class will have.

March 28, 2021 at 1:25pm
Here's the second one.
Note that these are both non standard workarounds and classes were never designed to support async construction, which is why there's no well defined/supported way to do that. I'd use a regular class + a factory function.
Do you know this famous quote?
Personally, I take it one step further and generally avoid classes for the majority of cases in order to avoid many of their inherent pitfalls and flaws.
like-fill
1