Created
February 27, 2013 19:41
-
-
Save anonymous/5051008 to your computer and use it in GitHub Desktop.
Mixin in typescript
This file contains 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
//Addapted from this page http://lostechies.com/derickbailey/2012/10/07/javascript-mixins-beyond-simple-object-extension/ | |
module Mixer { | |
// build a mixin function to take a target that receives the mixin, | |
// a source that is the mixin, and a list of methods / attributes to | |
// copy over to the target | |
export function mix(target, source, methodNames){ | |
// ignore the actual args list and build from arguments so we can | |
// be sure to get all of the method names | |
var args = Array.prototype.slice.apply(arguments); | |
target = args.shift(); | |
source = args.shift(); | |
methodNames = args.shift(); | |
var method; | |
var length = methodNames.length; | |
for(var i = 0; i < length; i++){ | |
method = methodNames[i]; | |
// build a function with a closure around the source | |
// and forward the method call to the source, passing | |
// along the method parameters and setting the context | |
target[method] = function(){ | |
var args = Array.prototype.slice.apply(arguments); | |
source[method].apply(source, args); | |
} | |
} | |
} | |
} | |
var $mx = Mixer; | |
module MixerTests { | |
export class NameOnly { | |
public name: string; | |
} | |
export class MultiMember { | |
name: string; | |
copyMe1: string; | |
copyMe2: string; | |
dontCopy1: string; | |
dontCopy2: string; | |
} | |
export function run() { | |
var target = new NameOnly(); | |
target.name = "target"; | |
var source = new MultiMember(); | |
source.name = "source"; | |
source.copyMe1 = "c1"; | |
source.copyMe2 = "c2"; | |
source.dontCopy1 = "d1"; | |
source.dontCopy2 = "d2"; | |
isMixinAndOnlyMixinApplied(target, source, ['copyMe1', 'copyMe2']); | |
} | |
export function isMixinAndOnlyMixinApplied(target, source, methodNames) { | |
var index = methodNames.length - 1, | |
sourceProps = Object.getOwnPropertyNames(source), | |
targetProps = Object.getOwnPropertyNames(target), | |
method; | |
$mx.mix(target, source, methodNames); | |
//Check to see that mix methods exist. | |
do { | |
method = methodNames[index]; | |
Assert.isTrue(target[method], method + ' exists'); | |
} while (index--); | |
index = sourceProps.length - 1; | |
method = ''; | |
//Check to see if non-mixed methods exist. | |
do { | |
method = sourceProps[index]; | |
if(methodNames.indexOf(method) !== -1 || targetProps.indexOf(method) !== -1) | |
continue; | |
Assert.isFalse(target[method], method + " does not exist as expected."); | |
} while (index--); | |
Assert.isTrue((<MultiMember>target).copyMe1 && true, "Type casting passes compiler check with intellisense."); | |
} | |
} | |
$(function () { | |
MixerTests.run(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment