Created
January 16, 2018 16:51
-
-
Save tomfun/c12d10fa74d183ce4b8a730a875b9355 to your computer and use it in GitHub Desktop.
Example of how to use decorators with typescript implementation to do pretty syntax abstract classes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function abstractMethod() { | |
return function (target, propertyKey: string, descriptor: PropertyDescriptor) { | |
console.log("am(): called"); | |
function abstractMethod() { | |
throw new TypeError('It is abstract method, this error should never be thrown') | |
} | |
abstractMethod.__abstractMethod = true; | |
descriptor.value = abstractMethod; | |
} | |
} | |
function abstractClass(constructor) { | |
return class AbstrctClass extends constructor { | |
constructor(...args) { | |
if (new.target === AbstrctClass) { | |
throw new TypeError(`Cannot construct ${constructor.name} instances directly it is abstract class`); | |
} | |
const notImplemented = []; | |
for (const method in constructor.prototype) { | |
if (new.target.prototype[method].__abstractMethod) { | |
notImplemented.push(method); | |
} | |
} | |
if (notImplemented.length) { | |
throw new TypeError(`You are extending abstract class ${constructor.name}, you must implement this methods: ${notImplemented}`) | |
} | |
super(...args); | |
} | |
} | |
} | |
@abstractClass | |
class A { | |
@abstractMethod() | |
abstractM1() {} | |
} | |
// var a = new A(); | |
// a.abstractMethod(); | |
@abstractClass | |
class B extends A { | |
@abstractMethod() | |
abstractM2() {} | |
} | |
class C extends B { | |
} | |
// Excpect error | |
// TypeError: You are extending abstract class B, you must implement this methods: abstractM2,abstractM1 | |
var c = new C(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment