TypeScript Mixins 概念介绍

简介: TypeScript Mixins 概念介绍

除了传统的 OO 层次结构,另一种从可重用组件构建类的流行方法是通过组合更简单的部分类来构建它们。 您可能熟悉 Scala 等语言的 mixin 或特征的想法,并且该模式在 JavaScript 社区中也很流行。


模式依赖于使用具有类继承的泛型来扩展基类。 TypeScript 最好的 mixin 支持是通过类表达式模式完成的。


看一个例子:


class Sprite {
  name = "";
  x = 0;
  y = 0;
  constructor(name: string) {
    this.name = name;
  }
}
type Constructor = new (...args: any[]) => {};
// This mixin adds a scale property, with getters and setters
// for changing it with an encapsulated private property:
function Scale<TBase extends Constructor>(Base: TBase) {
  return class Scaling extends Base {
    // Mixins may not declare private/protected properties
    // however, you can use ES2020 private fields
    _scale = 1;
    setScale(scale: number) {
      this._scale = scale;
    }
    get scale(): number {
      return this._scale;
    }
  };
}
const EightBitSprite = Scale(Sprite);
const flappySprite = new EightBitSprite("Bird");
flappySprite.setScale(0.8);
console.log('Ethan:' ,flappySprite.scale);

本例子和我之前的文章TypeScript 类装饰器的一个例子和使用单步调试搞清楚其运行原理其实很类似,只是没有使用装饰器语法罢了。


使用Scale 对 Sprite 进行装配,传入的是 Class Sprite 的定义:


image.png


返回的是一个新的函数,但只要不使用该函数去实例化新的类实例,函数体就不会执行。


现在准备使用 Scale 装饰过后的 Sprite 的扩展类去进行实例化操作了:


image.png


即将进入 mixin 内部:

image.png



首先执行基类的字段初始化逻辑:


image.png

然后才是子类字段的初始化逻辑:

image.png


Constrained Mixins

我们可以对上述 Mixins 做一些改造和增强。


在上面的形式中,mixin 没有类的基础知识,这会使创建你想要的设计变得困难。


比如,使用上面的 mixin,我们可以给任意的 Class 添加 _scale 属性。


image.pngimage.png




如果我们想对此做进一步限制,比如限制 Scale 只能装饰某些特定类型的 Class.


为了对此建模,我们修改原始构造函数类型以接受泛型参数。


// This was our previous constructor:
type Constructor = new (...args: any[]) => {};
// Now we use a generic version which can apply a constraint on
// the class which this mixin is applied to
type GConstructor<T = {}> = new (...args: any[]) => T;

现在,使用这个类型构造器,必须传入一个基类的类型作为类型参数:


image.png


type Spritable = GConstructor;

1

现在,Scale 装饰器只能修饰 Sprite 及其子类了:




现在,如果传入一个并非 Sprite 及其子类的方法进入 Scale 装饰器,会引起语法错误:


image.png



相关文章
|
12月前
TypeScript-类
TypeScript-类
44 0
|
4月前
|
JavaScript 前端开发 程序员
TypeScript 类
TypeScript 类
|
4月前
|
JavaScript 编译器
31.【TypeScript 教程】混入(Mixins)
31.【TypeScript 教程】混入(Mixins)
29 3
|
3月前
|
JavaScript 前端开发
TypeScript(七)类
TypeScript(七)类
31 0
|
4月前
|
JavaScript
TypeScript类
TypeScript类
|
5月前
|
存储 JavaScript 前端开发
TypeScript笔记(15)—— 深入理解TypeScript中的装饰器
TypeScript笔记(15)—— 深入理解TypeScript中的装饰器
82 0
|
5月前
|
JavaScript
解释如何使用 TypeScript 中的 mixin
解释如何使用 TypeScript 中的 mixin
43 0
|
5月前
|
JavaScript 安全
TypeScript中any unkown never的区别
TypeScript中any unkown never的区别
|
12月前
|
JavaScript 开发者
TypeScript-混入
TypeScript-混入
43 0
|
JavaScript 编译器
TypeScript深度剖析:TypeScript 中命名空间与模块的理解?区别?
TypeScript深度剖析:TypeScript 中命名空间与模块的理解?区别?
112 0