Skip to content

Instantly share code, notes, and snippets.

@aaronpowell
Created May 12, 2014 23:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronpowell/265830200143026d229d to your computer and use it in GitHub Desktop.
Save aaronpowell/265830200143026d229d to your computer and use it in GitHub Desktop.
Sweet.js classes combined with type-safe properties via ES6 Proxies
function Person(name) {
this.name = name;
return new Proxy(this, {
set: function (target, property, val) {
var currentType = typeof target[property];
var newType = typeof val;
if (property in target && currentType !== newType) {
throw new Error('Property ' + property + ' must be a ' + currentType);
}
target[property] = val;
}
});
}
Person.prototype.say = function say(msg) {
console.log(this.name + ' says: ' + msg);
};
var bob = new Person('Bob');
bob.say('Macros are sweet!');
bob.name = 42;
macro type {
rule { $this } => {
new Proxy($this, {
set: function (target, property, val) {
var currentType = typeof target[property];
var newType = typeof val;
if (property in target && currentType !== newType) {
throw new Error('Property ' + property + ' must be a ' + currentType);
}
target[property] = val;
}
});
}
}
macro class {
rule {
$className {
constructor ($cparams...) { $cbody ... }
$($mname $mparams $mbody) ...
}
} => {
function $className ($cparams ...) {
$cbody ...
return type this
}
$($className.prototype.$mname
= function $mname $mparams $mbody; ) ...
}
}
class Person {
constructor(name) {
this.name = name;
}
say(msg) {
console.log(this.name + " says: " + msg);
}
}
var bob = new Person("Bob");
bob.say("Macros are sweet!");
bob.name = 42;
@coderofsalvation
Copy link

Nice. A non-proxy way could by using typeshave, a lightweight typesafe function wrapper for nodejs/browse PLUG :)

Its 3.9K gzipped, supports jsonschema, and works pretty much everywhere. So:

foo = function(bar){

}

could be rewritten like so:

foo = typesafe({ 
  bar: { type: "object" } 
}, function(bar){

}

Or just wrapped later on, including validating deepnested structures, and optional args:

foo = typesafe({
  bar: { 
    type: "object", 
    required: true,
    properties: {
      foo: { type: "string", required:true },
      items: [{
        type: "integer"  
      }]
    }
  }
}, foo ); 

foo({ foo: "helloworld", items:[1,2,3] });

It looks less noisy in coffeescript imho

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment