码迷,mamicode.com
首页 > 其他好文 > 详细

TypeScript手册翻译系列8-常见错误与Mixins

时间:2015-10-04 22:25:22      阅读:313      评论:0      收藏:0      [点我收藏+]

标签:

常见错误

下面列出了在使用TypeScript语言和编译器期间,经常会遇到的一些常见错误。

"tsc.exe" exited with error code 1.

解决方案: 检查文件编码为UTF-8 - https://typescript.codeplex.com/workitem/1587

external module XYZ cannot be resolved

解决方案:检查模块路径是大小写敏感https://typescript.codeplex.com/workitem/2134

Mixins

Along with traditional OO hierarchies, another popular way of building up classes from reusable components is to build them by combining simpler partial classes. You may be familiar with the idea of mixins or traits for languages like Scala, and the pattern has also reached some popularity in the JavaScript community.

Mixin sample

In the code below, we show how you can model mixins in TypeScript. After the code, we‘ll break down how it works.

// Disposable Mixin
class Disposable {
    isDisposed: boolean;
    dispose() {        
        this.isDisposed = true;
    }
 


// Activatable Mixin
class Activatable {
    isActive: boolean;
    activate() {        
        this.isActive = true;
    }
    deactivate() {        
        this.isActive = false;
    }
}

class SmartObject implements Disposable, Activatable {
    constructor() {
        setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500);
    }
 
    interact() {        
        this.activate();
    }
    
    // Disposable
    isDisposed: boolean = false;
    dispose: () => void;    
    // Activatable
    isActive: boolean = false;
    activate: () => void;
    deactivate: () => void;
}
applyMixins(SmartObject, [Disposable, Activatable]) 

var smartObj = new SmartObject();
setTimeout(() => smartObj.interact(), 1000); 

////////////////////////////////////////
// In your runtime library somewhere
////////////////////////////////////////

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        })
    }); 
}

Understanding the sample

The code sample starts with the two classes that will act is our mixins. You can see each one is focused on a particular activity or capability. We‘ll later mix these together to form a new class from both capabilities.

// Disposable Mixin
class Disposable {
    isDisposed: boolean;
    dispose() {        
        this.isDisposed = true;
    }
 
}

// Activatable Mixin
class Activatable {
    isActive: boolean;
    activate() {        
        this.isActive = true;
    }
    deactivate() {        
        this.isActive = false;
    }
}


Next, we‘ll create the class that will handle the combination of the two mixins. Let‘s look at this in more detail to see how it does this:

class SmartObject implements Disposable, Activatable {


The first thing you may notice in the above is that instead of using ‘extends‘, we use ‘implements‘. This treats the classes as interfaces, and only uses the types behind Disposable and Activatable rather than the implementation. This means that we‘ll have to provide the implementation in class. Except, that‘s exactly what we want to avoid by using mixins. 

To satisfy this requirement, we create stand-in properties and their types for the members that will come from our mixins. This satisfies the compiler that these members will be available at runtime. This lets us still get the benefit of the mixins, albeit with a some bookkeeping overhead.

// Disposable
isDisposed: boolean = false;
dispose: () => void;
// Activatable
isActive: boolean = false;
activate: () => void;
deactivate: () => void;


Finally, we mix our mixins into the class, creating the full implementation.

applyMixins(SmartObject, [Disposable, Activatable])


Lastly, we create a helper function that will do the mixing for us. This will run through the properties of each of the mixins and copy them over to the target of the mixins, filling out the stand-in properties with their implementations.

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        })
    }); 
}

参考资料

[1] http://www.typescriptlang.org/Handbook#common-errors

[2] TypeScript系列1-简介及版本新特性, http://my.oschina.net/1pei/blog/493012

[3] TypeScript系列2-手册-基础类型, http://my.oschina.net/1pei/blog/493181

[4] TypeScript系列3-手册-接口, http://my.oschina.net/1pei/blog/493388

[5] TypeScript系列4-手册-类, http://my.oschina.net/1pei/blog/493539

[6] TypeScript系列5-手册-模块, http://my.oschina.net/1pei/blog/495948

[7] TypeScript系列6-手册-函数, http://my.oschina.net/1pei/blog/501273

[8] TypeScript手册翻译系列7-泛型, http://my.oschina.net/1pei/blog/513483

TypeScript手册翻译系列8-常见错误与Mixins

标签:

原文地址:http://my.oschina.net/1pei/blog/513499

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!