假设我想在一个项目中的单个函数中管理来自不同模块的服务,并根据获得的数据类型调用不同的服务。
例如,我有这两个 DTO:
class UserDto {
constructor (name: string) {
this.name = name
}
public name: string;
}
class CarDto {
constructor (brand: string) {
this.brand = brand
}
public brand: string;
}
这两项服务:
class UserService {
create(val: UserDto) {
// Create the user
return 'foo';
}
}
class CarService {
create(val: CarDto) {
// Create the car
return 'bar';
}
}
相当基础的东西。然后我可以使用一个能够根据接收到的数据类型来管理通话的服务。为此,我创建了一个联合类型,用于确定我接收到的数据类型以及应该调用哪个服务,就像这样:
type DataType =
| {
data: 'user';
dto: UserDto;
service: 'userService'
}
| {
data: 'car';
dto: CarDto;
service: 'carService'
}
最后,我想把这一切都放在一个管理这两个子服务的服务中的函数中,就像这样:
class MainService {
constructor (
private userService: UserService,
private carService: CarService,
) {}
serviceManager(val: DataType) {
// Call the right service here!
}
}
我不想做的是检查每个属性是否是我想要的。这就是我想要避免的事情。
serviceManager(val: DataType) {
const name = val.data;
if (name === 'user') this.userService.create(val.dto);
}
相反,我更喜欢一种方法,即TypeScript可以推断出我获取的服务以及我传递给该服务的信息。所以这就是我认为应该起作用的方式(剧透,它并不起作用)。
serviceManager(val: DataType) {
const func = this[val.service];
func.create(val.dto);
// Argument of type 'UserDto | CarDto' is not assignable to parameter of type 'UserDto & CarDto'.
// Type 'UserDto' is not assignable to type 'UserDto & CarDto'.
// Property 'brand' is missing in type 'UserDto' but required in type 'CarDto'.
}
最后,我决定走另一条路,甚至不使用子服务。但是,即使对于我现在正在处理的项目来说,我一直在努力寻找解决这个问题的方法,尽管它已经不相关了。
使用TypeScript是否可能以某种不同的方式声明DataType类型,或者这根本不可能?也许在声明子服务内部的函数时应该使用泛型?
serviceManager()
方法的问题。 - jcalzserviceManager()
方法的问题。 - jcalzserviceManager()
方法的问题。 - undefined