我正在尝试在TypeScript中编写一个通用存储库,该存储库使用localStorage进行序列化/反序列化。
我在ts中已经阅读了许多related regarding new()
个问题,但是它们充满了foos,bars和baze,我找不到真正的例子。最重要的是,我找不到一个可以在泛型类中创建新实例的示例(我发现的所有示例都假定类型是已知的,而您将在下面看到的存储库类中的类型是未知的)。>
“狗”实体:
interface IEntity { }
class Dog implements IEntity {
constructor(json: string); // called when deserializing
constructor(name: string, age: number);
constructor(jsonOrName: string, age?: number) { /* implementation... */ }
name: string;
age: number;
toJSON() { // called when serializing (via JSON.stringify)
//...
}
}
还有一个用于从localStorage进行序列化/反序列化的存储库。
class Repository<T extends IEntity> {
constructor(private key: string) { }
read(): T | null {
const s = localStorage.getItem(this.key);
if (!s) return null;
const value = JSON.parse(s);
return new T(value); // <----------- how do I do this?
}
write(value: T): void {
localStorage.setItem(this.key, JSON.stringify(value));
}
}
预期用途是:
const dogRepository = new Repository<Dog>("dog");
const dog = dogRepository.read();
if (dog) console.log(dog.name);
答案 0 :(得分:2)
类型系统在运行时完全为erased,因此名为T
的类型将不存在,因为您可以通过new
运算符构造任何东西。相反,您需要Respository<T>
实例来为T
保留一个实际的运行时构造函数。例如:
class Repository<T extends IEntity> {
// take a key *and* a constructor which operates on a json string
constructor(private key: string, private ctor: new (json: string) => T) {}
read(): T | null {
const s = localStorage.getItem(this.key);
if (!s) return null;
return new this.ctor(s); // use the ctor on the JSON (don't parse, right?)
}
write(value: T): void {
localStorage.setItem(this.key, JSON.stringify(value));
}
}
然后您也必须更改此设置:
const dogRepository = new Repository("dog", Dog); // pass ctor here, T is inferred
const dog = dogRepository.read();
if (dog) console.log(dog.name);
这有意义吗?希望能有所帮助。祝你好运!