nohm icon indicating copy to clipboard operation
nohm copied to clipboard

Unable to register Typescript Model

Open ghost opened this issue 6 years ago • 3 comments

The Typescript example shows the following:

import { Nohm, NohmModel, TTypedDefinitions } from 'nohm';

// We're gonna assume the basics are clear and the connection is set up etc. - look at the ES6 example otherwise.
// This example highlights some of the typing capabilities in nohm.

interface IUserProperties {
  email: string;
  visits: number;
}

class UserModel extends NohmModel<IUserProperties> {
  public static modelName = 'User';

  protected static definitions: TTypedDefinitions<IUserProperties> = {
    // because of the TTypedDefinitions we can only define properties keys here that match our interface keys
    // the structure of the definitions is also typed
    email: {
      type: 'string', // the type value is currently not checked. If you put a wrong type here, no compile error will appear.
      unique: true,
      validations: ['email'],
    },
    visits: {
      defaultValue: 0,
      index: true,
      type: function incrVisitsBy(value, _key, old): number {
        return old + value; // TS Error: arguments are all strings, not assignable to number
      },
    },
  };

  public getVisitsAsString(): string {
    return this.property('visits'); // TS Error: visits is number and thus not assignable to string
  }

  public static async loadTyped(id: string): Promise<UserModel> {
    // see main() below for explanation
    return userModelStatic.load<UserModel>(id);
  }
}

const userModelStatic = nohm.register(UserModel);

However, when using this exact setup I receive the following error: Error: Class is not extended properly. Use the return Nohm.register() instead of your class directly.

I am on Node v8.16.0

Tsconfig:

{
   "compilerOptions": {
      "lib": [
         "es7"
      ],
      "target": "es2017",
      "module": "commonjs",
      "outDir": "./build",
      "sourceMap": true
   }
}

Any help is appreciated.

ghost avatar Jul 16 '19 22:07 ghost

Maybe the example isn't quite clear here, since its only supposed to show the typing stuff, not how to generally use nohm. I'll look into fixing that.

nohm.register returns the class you are supposed to use, as explained here.

In the grand scheme a bigger refactoring to make this work with just the extended model would probably be good. I'm not sure anymore why I didn't change that back when I rewrote all of it for v2.

Here's the continuation of that example that will make use of the registered model:

const userModelStatic = Nohm.register(UserModel);

// some wrapping to make it work in a single file with async/await
const main = async () => {
  await redisConnector(); // a custom helper
  try {
    const user = new userModelStatic();

    user.property({ email: `[email protected]` });
    await user.save();

    try {
      const user2 = new UserModel(); // wrong invocation
      await user2.save(); // will not be reached
      console.error('This line should never appear!');
      process.exit(1);
    } catch (e) {
      console.info('As expected it failed:', e);
    }
  } finally {
    await redisCloser(); // a custom helper
  }
};

main().catch((err) => {
  console.error('Unexpected failure:', err);
});

maritz avatar Jul 17 '19 13:07 maritz

Sorry, I'm sick right now, my brain doesn't work quite right. The documentation is clearly missing that as well.

maritz avatar Jul 17 '19 14:07 maritz

@maritz no problem at all, thank you for the speedy response and for maintaining this package! If I end up writing good documentation internally I may submit a PR.

ghost avatar Jul 17 '19 15:07 ghost