如何在Typescript中创建类型安全服务注册表。基本上,这是一个根据参数返回具体类型的函数。
get("a") would return an object of type ServiceA.
get("b") would return an object of type ServiceB.我按照这里的答案:https://stackoverflow.com/a/47098963/12116498,但仍然收到输入错误。
我已经将我的问题简化为以下内容,并添加了我得到的类型错误:
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
}重要的是要将返回类型限定在较窄的范围内,而不是其他类型的联合。
发布于 2021-03-22 19:09:16
@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') // ModalServicehttps://stackoverflow.com/questions/66703040
复制相似问题