【问题标题】:Generic class not respecting type泛型类不尊重类型
【发布时间】:2019-07-08 03:53:53
【问题描述】:

我有以下代码:

class AugmentedSet<T>{
    private set: Set<T> = new Set<T>();

    add (item: any){
        this.set.add(item)
        item._parent = this;
    }
}

class Foo{}
class Bar{}

const foo = new Foo()
const bar = new Bar();
const augSet = new AugmentedSet<Foo>();
augSet.add(foo);
augSet.add(bar); // should not work, different type

我正在尝试创建一个增强Set 类的类。由于此示例中未显示的各种原因,我不想扩展Set,也不想修改文字Set 原型。相反,我只想创建一个类似 Set 的类型对象。

我期望发生的是 typescript 只允许通过 AugmentedSet.add() 添加 Foo 类,但它似乎允许 Foo 和 Bar。

我可能不明白如何正确键入此类/方法,所以我在这里寻找任何指导。 :)

【问题讨论】:

  • 您声明add 采用any,因此它采用任何对象。如果您希望它采用T,请将其参数声明为T 类型。
  • 为什么需要item._parent = this
  • item._parent = this 而言,这是一种将项目容器设置为增强集的方法,因此如果我们需要从项目获取集合本身,我们可以这样做。我有一个使用类似模式的更复杂的示例(我正在尝试移植的 python 代码),这只是演示目的的一种快速简单的方法。将其更改为 item: T 会使此父属性分配失败,因为 T 不知道 _parent :/

标签: typescript


【解决方案1】:

FooBar 在您的示例中由于结构类型而可以相互分配,并且它们具有相同的属性集。你可以试试:

let foo: Foo = new Bar() ; // will typecheck

这就是您的Set&lt;Foo&gt; 也接受Bars 的原因。只需在 Foo 和 Bar 类中添加一些不同的方法,即可获得预期的行为。

编辑 cmets 中的@Silvio 注意到了一些我没有注意到的东西,这是另一个更直接的原因。必须同时考虑两者才能获得预期的行为。

【讨论】:

  • 只是为了添加一些东西,因为这只是为了调试/学习目的,让两个类不能相互分配的一个非常简单的方法是给每个类一个私有字段。私有字段(即使它们共享名称)在不同的类中也不相同。
  • 谢谢!这更有意义,但是在制作item: T 时,我无法执行item._parent = this;,因为它在类型T 上不存在。这是T extends X 有用的情况吗?它是否扩展了一个已知包含这些属性的类?
  • 不要设置item._parent = this。没有人期望将一个对象添加到集合中来改变它。使用地图或符号必须有另一种解决方案。
猜你喜欢
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 2011-08-19
  • 2019-05-30
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
相关资源
最近更新 更多