sylvainpolletvillard / ObjectModel

Strong Dynamically Typed Object Modeling for JavaScript
http://objectmodel.js.org
MIT License
467 stars 30 forks source link

ES6 Classes duck type not working #63

Closed rafaferry closed 6 years ago

rafaferry commented 6 years ago

Hello,

I'm trying to use objectmodel with ES6 classes, but it seems that duck typing is not working. The message that the framework gives is: "Class constructor Person cannot be invoked without 'new'"

Here is a mocha test:

const expect = require('chai').expect;

const ObjectModel = require('objectmodel').Model;

describe('ES6 Classes test', () => {
  it('ES6', () => {
    const Person = class Person extends ObjectModel({
      name: String,
      age: [Number],
    }) {};

    const Lovers = class Lovers extends ObjectModel({
      husband: Person,
      wife: Person,
    }) {};

    const joe = { name: 'Joe', age: 42 };
    const ann = new Person({
      name: `${joe.name}'s wife`,
      age: joe.age - 5,
    });

    const couple = new Lovers({
      husband: joe, // object duck type does not work here.
      wife: ann, // object model
    });

    expect(couple.husband).to.be.an.instanceof(Person);
  });
});

if i change to

const couple = new Lovers({
      husband: new Person(joe), 
      wife: new Person(ann), // object model
    });

it works, but then I dont have the ducktyping.

[]s

sylvainpolletvillard commented 6 years ago

Hello,

Thanks for the report, Indeed, duck typing does not use the new operator.

Object Models can be instanciated with or without new thanks to a additional check I added in their constructor code. But in the case of ES6 classes, the ES6 specification explicitely requires that classes have to be instanciated with new.

On the other hand, when duck typing is used on some primitives, the new operator may cause unexpected issues such as converting to primitive wrappers (i.e. string => String). I need to make additional checks. Bugfix coming tonight hopefully

sylvainpolletvillard commented 6 years ago

Fixed in v3.4.3: https://github.com/sylvainpolletvillard/ObjectModel/commit/2db66d2b42da7c28275d0619d051e7a4769f9e71