首页 > 解决方案 > 将泛型类的实例存储在地图中,同时保持正确键入

问题描述

在 TypeScript 中,我想将泛型类(此处为 class Foo)的实例存储在Map.

但是,我没有得到想要的结果,因为自从使用any. 有什么办法可以完成吗?

我不确定使用Record或键入别名可能值得一看。

class Foo<T> {
  t: T;
}

class Bar {

  // Use of any because I am not sure about the right way
  map: Map<string, any> = new Map();
}

const bar = new Bar();

bar.map.set('numberEntry', new Foo<number>());
bar.map.set('stringEntry', new Foo<string>());

const n = bar.map.get('numberEntry').t;
const s = bar.map.get('stringEntry').t;

console.log(typeof n); // undefined; should be 'number'
console.log(typeof s); // undefined; should be 'string'

如果需要更多详细信息,请告诉我。

标签: typescript

解决方案


首先typeof n是运行时检查,我们这里有运行时问题,因为我们的 Foo 实例在 field 中没有值t。代码中没有分配此字段。使用t 字段new Foo<number>()创建Foo实例。undefined我们需要以某种方式通过 t。我们可以通过以下方式修复它:

class Foo<T> {
  t: T;
  constructor(t: T) {
    this.t = t;
  }
}

现在关于键入和使用any.

如果我们使用Set,则不可能将集合的键与特定的值类型匹配。我们可以说这个集合有一些可能的类型,在这个例子中它是:

Map<string, Foo<string | number>> = new Map();

完整的工作代码

所以我们在我们的地图中说,我们存储Foo了一个stringnumber字段的值。


顺便提一句。如果我们想要键 -> 值类型关系,我们应该使用 POJO:

const map: {
  numberEntry: Foo<number>;
  stringEntry: Foo<string>;
} = {
  numberEntry: new Foo(1),
  stringEntry: new Foo("a")
};

推荐阅读