kube/monolite

Preserve the prototype when setting in an object

Closed this issue · 6 comments

It would be good if set preserved the prototype, so that it can be used with instances of classes with methods.

I'm working on a merge request right now. I have to figure out how to tag this issue.

kube commented

Do you have an example use case for this?

I'm not really convinced by keeping prototypes on objects handled my Monolite, but I could change my mind if you show a concrete use-case for this.

Here is the use case I have in mind:

class Person {
    constructor(public firstName: string, public lastName: string) {}
    fullName(): string { return `${firstName} ${lastName}`; }
}

const person1 = new Person('Adam', 'West');
const person2 = set(person1, _ => _.lastName)('Savage');

person1.fullName();  // 'Adam West'
person2.fullName();  // Should be 'Adam Savage', but currently will cause an error

Also, it just seems right that x instanceof y if and only if set(x, f)(a) instanceof y, which requires that the prototype be preserved.

Note, lodash/fp set preserves the proto correctly:

m = require('monolite')
f = require('lodash/fp')

class C { constructor() { this.a = 1}}
var obj = new C()

m.set(obj, _ => _.a)(3) instanceof C  //=> false
f.set(['a'], 3, obj)    instanceof C  //=> true

I think monolite must also preserve the proto, is the more useful, well-typed and unsurprising behavior.

kube commented

Ok, Nominal Typing convinced me.

I will add support for prototype tomorrow. (Your PR cannot be merged as I changed a lot of things in Monolite since, and in particular passed from Mocha to Jest)