[英]TypeScript type-safe service registry
How can I create a type-safe service registry in Typescript.如何在 Typescript 中创建类型安全的服务注册表。 Basically, a function that returns a concrete type based on the argument.
基本上,一个 function 根据参数返回一个具体类型。
get("a") would return an object of type ServiceA.
get("b") would return an object of type ServiceB.
I followed the answer from here: https://stackoverflow.com/a/47098963/12116498 but am still getting typing errors.我从这里得到了答案: https://stackoverflow.com/a/47098963/12116498但我仍然遇到打字错误。
I have reduced my problem to the following and added the type errors I am getting:我已将我的问题减少到以下内容,并添加了我得到的类型错误:
console.log("Test get");
console.log("Get foo from AlertsService:", get('AlertsService').foo);
console.log("Get foo from AlertsService:", get('ModalService').foo);
console.log("Get foo from AlertsService:", get('ModalService').bar);
function get<T extends keyof ServiceMapping>(serviceType: T): ServiceMapping[T] {
const t: keyof ServiceMapping = serviceType;
switch (t) {
case 'AlertsService':
// TS2322: Type '{ type: "AlertsService"; foo: string; }' is not assignable to type 'ServiceMapping[T]'.
// Type '{ type: "AlertsService"; foo: string; }' is not assignable to type 'never'.
// The intersection 'AlertsService & ModalService' was reduced to 'never' because property 'type' has conflicting types in some constituents.
return {
type: 'AlertsService',
foo: 'testing'
};
case 'ModalService':
// TS2322: Type '{ type: "ModalService"; foo: string; bar: string; }' is not assignable to type 'ServiceMapping[T]'.
// Type '{ type: "ModalService"; foo: string; bar: string; }' is not assignable to type 'never'.
// The intersection 'AlertsService & ModalService' was reduced to 'never' because property 'type' has conflicting types in some constituents.
return {
type: 'ModalService',
foo: 'testing',
bar: 'bar test'
};
default:
throw new Error("nope");
}
}
export type ServiceMapping = {
AlertsService: AlertsService;
ModalService: ModalService;
}
export type AlertsService = {
type: 'AlertsService',
foo: string
}
export type ModalService = {
type: 'ModalService',
foo: string,
bar: string
}
It is important to have the return type be narrowly scoped and not a union of other types.返回类型的范围很窄,而不是其他类型的联合,这一点很重要。
@kruschid please tell me why overloadings are bad @kruschid 请告诉我为什么重载不好
type AlertsService = {
type: 'AlertsService',
foo: string,
}
type ModalService = {
type: 'ModalService',
foo: string,
bar: string
}
function get<T extends 'AlertsService'>(arg: 'AlertsService'): AlertsService
function get<T extends 'ModalService'>(arg: T): ModalService
function get<T extends 'AlertsService' | 'ModalService'>(arg: T) {
switch (arg) {
case 'AlertsService':
return {
type: 'AlertsService',
foo: 'testing'
};
case 'ModalService':
return {
type: 'ModalService',
foo: 'testing',
bar: 'bar test'
};
default:
throw new Error("nope");
}
}
const result = get('AlertsService') // AlertsService
const result2 = get('ModalService') // ModalService
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.