Skip to content

Instantly share code, notes, and snippets.

@ebrehault
Forked from bloodbare/adapter.ts
Last active May 31, 2016 15:11
Show Gist options
  • Save ebrehault/a12c69bc9940bb83abb2d4bba6ecfbe5 to your computer and use it in GitHub Desktop.
Save ebrehault/a12c69bc9940bb83abb2d4bba6ecfbe5 to your computer and use it in GitHub Desktop.
TypeScript version of adaptation (ZTK)
let registry:any = {}
function implementing(typeInterface: any) {
return (target: any) => {
if (target.providesInterfaces === undefined) {
target.providesInterfaces = [typeInterface];
} else {
target.providesInterfaces.push(typeInterface);
}
return target;
}
}
function logClass(target: any) {
// save a reference to the original constructor
var original = target;
// a utility function to generate instances of a class
function construct(constructor, args) {
var c : any = function () {
return constructor.apply(this, args);
}
c.prototype = constructor.prototype;
return new c();
}
// the new constructor behaviour
var f : any = function (...args) {
console.log("New: " + original.name);
return construct(original, args);
}
// copy prototype so intanceof operator still works
f.prototype = original.prototype;
// return new constructor (will override original)
return f;
}
function adapts(context: any, name: string) {
return (target: any) => {
if (registry[context] === undefined) {
registry[context] = {};
}
if (registry[context][name] !== undefined) {
console.log('Already defined');
} else {
registry[context][name] = target;
}
}
}
function getAdapter1(context: any, destiny: any, name?: string) {
if (name === undefined) {
name = '';
}
let found = undefined;
// we need the class of the
for (var index = 0; index < context.constructor.providesInterfaces.length; index++) {
if (context.constructor.providesInterfaces[index] in registry) {
found = registry[context.constructor.providesInterfaces[index]]
}
if (found && (name in found)) {
return new found[name](context)
} else {
throw "Not found";
}
}
if (found === undefined) {
throw "Not found class"
}
}
interface IBaseContent {
}
class IBaseContent implements IBaseContent {
}
interface IView {
render(): string
}
class IView implements IView{
constructor(public context: IBaseContent) {
}
render() { return ""}
}
// Page
interface IPage {
title: string;
}
class IPage implements IPage {
}
@implementing(IPage)
class Page extends IBaseContent{
constructor(public id: string, public title: string) {
super();
}
}
@implementing(IView)
@adapts(IPage, 'view')
@logClass
class PageView implements IView {
constructor(public context: Page) {
}
render() {
return "This is the view " + this.context.title;
}
}
let context = new Page("front-page", "Welcome");
let view = getAdapter1(context, IView, 'view')
console.log(view.render())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment