从存储库中获取模型,而无需通过尖括号指定类型
Get model from repository without having to specify type through angle brackets
我想创建一个包含许多不同模型的存储库。从存储库中获取其中一个模型时,我希望打字稿知道模型的类型,而不必手动指定它是哪种类型。
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 关键字吗?
假设在您的存储库中,每种类型的模型只有一个实例,那么简化代码的一种可能方法是使用 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 无法知道哪个键引用哪个类型,除非相关性是固定的并且您在代码中的某处定义了相关性。
我想创建一个包含许多不同模型的存储库。从存储库中获取其中一个模型时,我希望打字稿知道模型的类型,而不必手动指定它是哪种类型。
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 关键字吗?
假设在您的存储库中,每种类型的模型只有一个实例,那么简化代码的一种可能方法是使用 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 无法知道哪个键引用哪个类型,除非相关性是固定的并且您在代码中的某处定义了相关性。