Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble with Init() #52

Closed
danvk opened this issue Sep 8, 2016 · 13 comments
Closed

Trouble with Init() #52

danvk opened this issue Sep 8, 2016 · 13 comments

Comments

@danvk
Copy link

danvk commented Sep 8, 2016

I wrote code that looks like this:

import {DataTypes, Model, Sequelize} from 'sequelize';

class SavedQuery extends Model {
  id: number;
  name: string;
  description: string;
  author: string;
  mtime: Date;
}

const sequelize = new Sequelize(config.database, config.user, config.password, sqlConfig);

  SavedQuery.init({
    name: DataTypes.STRING,
    description: DataTypes.STRING,
    author: DataTypes.STRING,
    mtime: DataTypes.DATE,
  }, {sequelize});

This type checks fine using sequelize@4.0.0-1 and typed-sequelize@4.0.0-1. But when I run it I get this error:

  SavedQuery.init({
             ^
TypeError: SavedQuery.init is not a function

Is there something I'm missing here? I'm going straight off the test cases.

@felixfbecker
Copy link
Collaborator

Well it is a runtime error... Do you actually have sequelize@4.0.0-1 installed? If you use a debugger, what kind of object is SavedQuery?

@danvk
Copy link
Author

danvk commented Sep 8, 2016

Pretty sure I'm running the right version:

> const sequelize = require('sequelize');
undefined
> sequelize.version
'4.0.0-1'

Here are the methods I see:

> console.log(SavedQuery);
{ [Function: SavedQuery]
  findByPrimary: [Function: findById],
  find: [Function: findOne],
  findAndCountAll: [Function: findAndCount],
  findOrInitialize: [Function: findOrBuild],
  insertOrUpdate: [Function: upsert],
  hasMany: [Function: hasMany],
  belongsToMany: [Function: belongsToMany],
  getAssociation: [Function: getAssociation],
  hasOne: [Function],
  belongsTo: [Function],
  Mixin:
   { hasMany: [Function: hasMany],
     belongsToMany: [Function: belongsToMany],
     getAssociation: [Function: getAssociation],
     hasOne: [Function],
     belongsTo: [Function],
     Mixin: [Circular],
     default: [Circular] },
  default:
   { hasMany: [Function: hasMany],
     belongsToMany: [Function: belongsToMany],
     getAssociation: [Function: getAssociation],
     hasOne: [Function],
     belongsTo: [Function],
     Mixin: [Circular],
     default: [Circular] },
  replaceHookAliases: [Function: replaceHookAliases],
  runHooks: [Function: runHooks],
  hook: [Function: hook],
  addHook: [Function: addHook],
  removeHook: [Function: removeHook],
  hasHook: [Function: hasHook],
  hasHooks: [Function: hasHook],
  beforeValidate: [Function],
  afterValidate: [Function],
  validationFailed: [Function],
  beforeCreate: [Function],
  afterCreate: [Function],
  beforeDestroy: [Function],
  afterDestroy: [Function],
  beforeRestore: [Function],
  afterRestore: [Function],
  beforeUpdate: [Function],
  afterUpdate: [Function],
  beforeSave: [Function],
  afterSave: [Function],
  beforeUpsert: [Function],
  afterUpsert: [Function],
  beforeBulkCreate: [Function],
  afterBulkCreate: [Function],
  beforeBulkDestroy: [Function],
  afterBulkDestroy: [Function],
  beforeBulkRestore: [Function],
  afterBulkRestore: [Function],
  beforeBulkUpdate: [Function],
  afterBulkUpdate: [Function],
  beforeFind: [Function],
  beforeFindAfterExpandIncludeAll: [Function],
  beforeFindAfterOptions: [Function],
  afterFind: [Function],
  beforeCount: [Function],
  beforeDefine: [Function],
  afterDefine: [Function],
  beforeInit: [Function],
  afterInit: [Function],
  beforeConnect: [Function],
  beforeSync: [Function],
  afterSync: [Function],
  beforeBulkSync: [Function],
  afterBulkSync: [Function],
  beforeDelete: [Function],
  afterDelete: [Function],
  beforeBulkDelete: [Function],
  afterBulkDelete: [Function],
  beforeConnection: [Function] }

@felixfbecker
Copy link
Collaborator

No, those are not all methods, as methods are not enumerable.

@danvk
Copy link
Author

danvk commented Sep 8, 2016

I've got this running in a debugger now. What would you like to know about SavedQuery, exactly?

> typeof SavedQuery
"function"

It doesn't have an Init method, of course.

@felixfbecker
Copy link
Collaborator

typeof SavedQuery.init
typeof Model
typeof Model.init

@felixfbecker
Copy link
Collaborator

Running this in the REPL works correctly:

felix@FELIX-SURFACE ~\git\OpenSource\sequelize [master ≡]
$ node
> typeof require('.').Model
'function'
> require('.').Model.init
[Function: init]

It may be a problem with your TypeScript config. Could you tell me which target setting you are using, and paste the compiled JavaScript of your file?

@danvk
Copy link
Author

danvk commented Sep 9, 2016

The issue is that the static method isn't inherited:

> typeof(SavedQuery)
'function'
> typeof(SavedQuery.Init)
'undefined'
> typeof(Model)
'function'
> typeof(Model.Init)
'function'

@felixfbecker
Copy link
Collaborator

Please show me the generated Javascript and your tsconfig.json.

@danvk
Copy link
Author

danvk commented Sep 9, 2016

Thanks for the help!

tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "jsx": "react",
        "noEmit": false,
        "sourceMap": true
    },
    "exclude": [
        "node_modules",
        "typings/main",
        "typings/main.d.ts"
    ]
}

and generated JS for the class:

"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var sequelize_1 = require('sequelize');
var SavedQuery = (function (_super) {
    __extends(SavedQuery, _super);
    function SavedQuery() {
        _super.apply(this, arguments);
    }
    return SavedQuery;
}(sequelize_1.Model));

    var sequelize = new sequelize_1.Sequelize(config.database, config.user, config.password, sqlConfig);
    console.log('typeof(SavedQuery)', typeof (SavedQuery));
    console.log('typeof(SavedQuery.Init)', typeof (SavedQuery.init));
    console.log('typeof(Model)', typeof (sequelize_1.Model));
    console.log('typeof(Model.Init)', typeof (sequelize_1.Model.init));
    SavedQuery.init({
        name: sequelize_1.DataTypes.STRING,
        description: sequelize_1.DataTypes.STRING,
        author: sequelize_1.DataTypes.STRING,
    }, { sequelize: sequelize });

@felixfbecker
Copy link
Collaborator

The issue is that TS just copies static enumerable properties with for in, and methods are not enumerable. It should use Object.getOwnPropertyNames() or Object.setPrototypeOf() like Babel.
You shoul open an issue at the TypeScript repo.

This does not happen with target: ES6.

@danvk
Copy link
Author

danvk commented Sep 9, 2016

I think this is relevant? microsoft/TypeScript#1520

@danvk
Copy link
Author

danvk commented Sep 9, 2016

I'm satisfied that this is WAI from the perspective of typed-sequelize. Feel free to close the issue. My one request would be to document that typed-sequelize@4 is only compatible with target: es6.

@felixfbecker
Copy link
Collaborator

felixfbecker commented Sep 9, 2016

It is somewhat related. Will you open a new issue and reference it so I can track it? Feel free to do a PR to update the README, preferably with a link to the new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants