typescript - 键值对的 TypeScript 类型别名
问题描述
我有一个界面:
export interface PostEventTypeMap {
changePrice: number;
changeQuantity: number;
signalConnected: boolean;
signalDisconnected: boolean;
}
我如何定义一个类型别名,如:
type PostEvent = {
type: keyof PostEventTypeMap,
value: **Value based on key value and PostEventTypeMap**
};
我不能使 postEvent 属性通用:
PostBoxService {
get postEvent(): Observable<PostEvent> {
return getOrCreateValue(this, "postEvent", () => new BehaviorSubject(null));
}
}
服务用例:
postBoxService
.postEvent
.subscribe(event => {
if (!event)
return;
switch (event.type) {
case "changePrice":
this.changePrice(event.value);
break;
case "changeQuantity":
this.changeQuantity(event.value);
break;
}
});
解决方案
因为您有有限数量的可能性,并且由于该type
值始终是文字类型,所以您可以将其设为可区分的 union。一种方法是将属性映射PostEventTypeMap
到所需的联合成员,然后立即查找这些属性以获取联合:
type ObjToTypeValueUnion<T extends object> =
{ [K in keyof T]-?: { type: K, value: T[K] } }[keyof T]
type PostEvent = ObjToTypeValueUnion<PostEventTypeMap>;
/* type PostEvent = {
type: "changePrice";
value: number;
} | {
type: "changeQuantity";
value: number;
} | {
type: "signalConnected";
value: boolean;
} | {
type: "signalDisconnected";
value: boolean;
} */
您可以验证这是否适合您的用例:
declare function changePrice(x: number): void;
declare function changeQuantity(x: number): void;
((event?: PostEvent) => {
if (!event)
return;
switch (event.type) {
case "changePrice":
changePrice(event.value);
break;
case "changeQuantity":
changeQuantity(event.value);
break;
}
});
推荐阅读
- azure-active-directory - Microsoft Graph - 如何为用户扩展属性“过滤”
- python - 使用 LCG 方法生成随机数
- flutter - 构建模块“nanopb”时无法构建 iOS 应用程序
- rest - 谁能理解我的托管heroku问题
- sql - 在 oracle 中同时执行 when 和 else 部分时执行 case
- asp.net-core - 在作为 Windows 服务运行的自包含 .Net Core Web 应用程序中的嵌套 DLL 引用问题
- javascript - How to validate select input field using React Hook Form?
- mysql - 我可以对选择范围的数据使用什么功能?
- c - 自定义 PAM 在 SSH 中的 PAM_CONVERSATION 失败
- python - AttributeError:'tuple'对象没有属性'write',实例分割python