我想创建一个包含许多不同模型的存储库。从存储库中获取模型之一时,我希望Typescript知道模型的类型,而不必手动指定它是哪种类型。
export class Repository {
items = {};
add<T>(name: string, item: T) {
this.items[name] = item;
}
get(name: string) {
return this.items[name];
}
}
class BaseModel {
insert() {}
}
class ImageModel extends BaseModel {
displayImage() {}
}
class UserModel extends BaseModel {
doSomething() {}
}
class DataService {
repository: Repository = new Repository();
}
const service = new DataService();
service.repository.add<ImageModel>('image', new ImageModel());
service.repository.add<UserModel>('user', new UserModel());
const imageModel = <ImageModel>service.repository.get('image');
const userModel = <UserModel>service.repository.get('user');
imageModel.displayImage();
userModel.doSomething();
现在,当我从存储库中获取模型时,例如,我说变量imageModel
的类型为ImageModel,而userModel
的类型为UserModel。有没有办法让编译器知道它分别是ImageModel和UserModel类型,而不必在从存储库中获取它时指定它?可以通过使用泛型和/或infer关键字吗?
答案 0 :(得分:0)
假设在您的存储库中,每种类型的模型都只有一个实例,那么简化代码的一种可能方法是使用Map
并将构造函数用作键。从下面的示例中可以看到,这可以使您的代码更加简单和简洁。
class Repository {
items: Map<Function, BaseModel> = new Map();
add<T extends BaseModel>(item: T) {
this.items.set(item.constructor, item);
}
get<T extends BaseModel>(type: new () => T) {
return this.items.get(type)! as T;
}
}
class BaseModel {
insert() { }
}
class ImageModel extends BaseModel {
displayImage() { }
}
class UserModel extends BaseModel {
doSomething() { }
}
class DataService {
repository: Repository = new Repository();
}
const service = new DataService();
service.repository.add(new ImageModel()); // Now you don't need to specify anything here
service.repository.add(new UserModel());
const imageModel = service.repository.get(ImageModel); // As simple as it can possibly be
const userModel = service.repository.get(UserModel);
imageModel.displayImage(); // It works! TypeScript knows imageModel is an ImageModel
userModel.doSomething();
如果必须使用字符串作为键来识别模型,并且键可能会更改,那么我必须同意Aluan Haddad的观点,即您想要的东西是不可能的。除非相关性是固定的,并且您在代码中的某个位置定义了相关性,否则TypeScript不可能知道哪个键指向哪种类型。