TypeScript中,mixin和交叉类型有何区别?

3
我正在查看TypeScript文档并尝试使用提供的实用程序方法在TypeScript中尝试交叉类型混入示例,我从这两种方法中看到了基本相同的行为和结果。最终,我得到了一个对象,该对象是1..n其他类型接口的组合。以下是我在编码示例中使用的方法,它们直接来自TypeScript文档。
这用于在TypeScript中应用混入
function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
        });
    });
}

这是我用于“交集类型”的代码:
function extend<First, Second>(first: First, second: Second): First & Second {
    const result: Partial<First & Second> = {};
    for (const prop in first) {
        if (first.hasOwnProperty(prop)) {
            (<First>result)[prop] = first[prop];
        }
    }
    for (const prop in second) {
        if (second.hasOwnProperty(prop)) {
            (<Second>result)[prop] = second[prop];
        }
    }
    return <First & Second>result;
}

除了 mixins 方法需要一个数组,而 intersection type 方法特别需要 2 个值之外,从行为的角度来看,它们最终的表现是相同的。如果我有一个 Person 和一个 User 类,每个类都有单独的属性和方法,在使用上述任一方法后,我都可以创建一个新实例,该实例可以从 intersection typemixin 定义的类型中选择,并查看来自 PersonUser 的所有内容的组合。

具有讽刺意味的是,这正是我想要的,但我觉得我错过了何时使用哪种方法的目的。我进行了一些搜索,找到了与 JavaScript 相关的这篇文章(What's the difference between mixin() and extend() in Javascript libraries),但我不确定在这种情况下 extend 是否与 TypeScript 中的 intersection type 相同(即使帮助程序被称为这个)。

看这两个辅助方法,它们似乎都会将 A 的属性复制或定义到 B 中,就像预期的那样。请问有人可以解释一下 TypeScript 中这两种方法的区别,以及为什么会选择其中一种方法而不是另一种吗?

1个回答

2
我会尽力给出我的意见。 Mixins旨在通过其他对象提供的功能来修改类定义。它们作用于原型,因此对所有实例(包括已经创建的和未来的)都产生影响。 Intersections旨在扩展一个给定实例的属性,而不改变原始实例。事实上,返回的对象是全新的实例。
"Original Answer"翻译成"最初的回答"
const result: Partial<First & Second> = {};

在我看来,这两者的区别非常大。如果不对原型进行处理,那么得到的只是一个单一的、可丢弃的实例。由于没有反映在类原型中,因此同一类的实例不会受到更改的影响。

“最初的回答”翻译成英文是"Original Answer"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接