1

How would one rewrite this class to a plain object?

class ExampleClass {
    firstPropery: number = 0;
    secondProperty!: string;

  async exampleMethod(): Promise<void> {
    const { secondProperty } = await SomeHelperClass.exampleRequest();
    this.secondProperty = secondProperty;
  }
}

I would think it's something similar as this

interface IExample {
  firstProperty: number;
  secondProperty: string;
  exampleMethod: () => Promise<void>;
}

const Example: IExample = {
  firstProperty: 0,
  exampleMethod: async (): Promise<void> => {
    const { secondProperty } = await SomeHelperClass.exampleRequest();
    ...
  }
}

But how to set the secondProperty via the exampleMethod? In the class method I can just write this.secondProperty = ..., which I cannot do in the plain object.

My second question is, with the class I would make a new object like this const newObject = new ExampleClass();. With the plain object way, how would I make a new object instance?

Any help is gladly appreciated!

PTheory
  • 13
  • 2

1 Answers1

1

In the class method I can just write this.secondProperty = ..., which I cannot do in the plain object.

Actually you can. It doesn't matter whether it's defined in a class or object literal, exampleMethod is still a method and when called as example.exampleMethod() it will have its this point to example. However, you cannot use an arrow function to define it - use method syntax instead:

const example: IExample = {
  firstProperty: 0,
  async exampleMethod(): Promise<void> {
    const { secondProperty } = await SomeHelperClass.exampleRequest();
    ...
  }
}

With the class I would make a new object like this const newObject = new ExampleClass();. With the plain object way, how would I make a new object instance?

You write the code again and again. Or you use Object.assign to copy the method onto a new object. Or you place the object literal inside a function that you can call multiple times.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Ah, thank you, that works wonderful. However, the thing is in the class I don't set `secondProperty` immediately, but it is set when called like this: `const exObj = new ExampleClass();` and `exObj.exampleMethod();`. In the class way, I could just write `secondProperty!: string` since I know it will never be null or undefined, because I always call the `exampleMethod()` to set it up... but TypeScript complains that `secondProperty` is missing (since its defined in the interface) with the plain object way and it does not let me set the exclamation thingy. What to do there? – PTheory Oct 25 '21 at 16:01
  • @PTheory "*I know it will never be null or undefined*" - actually you're wrong there and TypeScript is right. Even if you immediately call the `exampleMethod`, the `exampleRequest` is asynchronous and until that promise fulfills, `secondProperty` stays `undefined`. If you want to make the same mistake in the object literal, it's `secondProperty: undefined!`, but I wouldn't recommend that :-) – Bergi Oct 25 '21 at 16:20
  • @PTheory My recommendation would be to remove the `exampleMethod` from the interface, and instead write a `getExample(): Promise` function that does the request and returns a promise for the `Example` instance with first and second property. – Bergi Oct 25 '21 at 16:21