Skip to content

Instantly share code, notes, and snippets.

@bitsmanent
Last active April 7, 2023 08:51
Show Gist options
  • Save bitsmanent/71096c3eb4fff3fc54a1bd1944f06f82 to your computer and use it in GitHub Desktop.
Save bitsmanent/71096c3eb4fff3fc54a1bd1944f06f82 to your computer and use it in GitHub Desktop.
interfaces.js
/* quick-and-dirty */
const Types = {
string: x => typeof x == "string",
number: x => typeof x == "number"
};
const Interface = model => {
const check = scope => {
let fails = 0;
Object.keys(model).forEach(prop => {
if(scope[prop] === undefined) {
console.error(`${prop}: field is required`);
++fails;
}
});
return fails;
};
const newscope = () => {
return new Proxy({}, {
set(target, prop, value) {
const type = model[prop];
const typecheck = type ? Types[type] : null;
if(type) {
if(!typecheck)
console.warn(`${type}: unknown type`);
else if(!typecheck(value))
console.error(`${prop}: expect a ${type}`);
}
target[prop] = value;
return true;
}
});
};
const concretizes = fn => {
const scope = newscope();
fn(scope);
return check(scope) ? null : scope;
}
return concretizes;
}
@bitsmanent
Copy link
Author

Example usage

const ShapeInterface = Interface({
	base: "number",
	height: "number"
});

/* direct */
const Triangle = ShapeInterface(self => {
	self.base = 2;
	self.height = 5;
	self.calculateArea = () => (self.base * self.height) / 2;
});
console.log("Triangle", Triangle.calculateArea());

/* instance */
function InstanceTriangle(base, height) {
	return ShapeInterface(self => {
		self.base = base;
		self.height = height;
		self.calculateArea = () => (self.base * self.height) / 2;
	});
}
const it = new InstanceTriangle(5,5); /* new is optional */
console.log("InstanceTriangle", it.calculateArea());

/* automatic instance */
const AutoTriangle = (base, height) => ShapeInterface(self => {
	self.base = base;
	self.height = height;
	self.calculateArea = () => (self.base * self.height) / 2;
});
const at = AutoTriangle(3,3);
console.log("AutoTriangle", at.calculateArea());

/* class */
class TriangleClass {
	constructor(base, height) {
		this.base = base;
		this.height = height;
		ShapeInterface(self => Object.assign(self, this));
	}

	calculateArea() {
		return (this.base * this.height) / 2;
	}
}
const tc = new TriangleClass(5,6);
console.log("TriangleClass", tc.calculateArea());

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