繁体   English   中英

Typescript 递归推断 object 值

[英]Typescript recursively infer object values

假设我有这个 AnalyticsService class

export class AnalyticsService {
  static sendAnalytics(eventName: string) {
    console.log(eventName);
    // logic here...
  }

  static EVENTS = {
    Header: {
      LogoClicked: "Header: Logo Clicked",
    },
    UserMenu: {
      LoginButtonClicked: "User Menu: Login Button Clicked",
      LogoutButtonClicked: "User Menu: Logout Button Clicked",
    }
  };
}

我使用这个 class 来发送分析,例如:

AnalyticsService.sendAnalytics(AnalyticsService.EVENTS.Header.LogoClicked)

我想将EVENTS的所有值提取到联合类型,以确保sendAnalytics function 仅获取现有事件名称

例如,这里的结果应该是: "Header: Logo Clicked" | "User Menu: Login Button Clicked" | "User Menu: Logout Button Clicked" "Header: Logo Clicked" | "User Menu: Login Button Clicked" | "User Menu: Logout Button Clicked"

typescript 甚至可以吗?

如果是这样,当它是一个相当大的 object 时,它是否会显着降低 typescript 的性能?

编辑:只是为了澄清EVENTS object 可以真正嵌套(为了简单起见,我举了一个小例子)

以下是正确键入sendAnalytics

type Keys = typeof AnalyticsService.EVENTS[keyof typeof AnalyticsService.EVENTS]

type UnionToIntersection<U> =
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

type FlattenedEvents = UnionToIntersection<Keys>;

type EventNames = FlattenedEvents[keyof FlattenedEvents];

export class AnalyticsService {
  static sendAnalytics(eventName: EventNames) {
    console.log(eventName);
    // logic here...
  }

  static EVENTS = {
    Header: {
      LogoClicked: "Header: Logo Clicked",
    },
    UserMenu: {
      LoginButtonClicked: "User Menu: Login Button Clicked",
      LogoutButtonClicked: "User Menu: Logout Button Clicked",
    }
  } as const;
}

AnalyticsService.sendAnalytics(AnalyticsService.EVENTS.Header.LogoClicked); // OK
AnalyticsService.sendAnalytics('test'); // KO

TypeScript操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM