Typescript: How to convert a string to a type

北战南征 提交于 2020-11-24 13:31:28

问题


I am creating a bunch of web components and each of them can emit custom events. As an example here are two simple examples:

//MyButton
emits 'myButtonPressed' and detail of this type:
interface ButtonDetailType {
  id: string;
}

//MySlider
emits 'mySliderChanging' and details of this type:
interface SliderChangingDetailType {
  id: string;
  value: number;
}
emits 'mySliderChanged' and details of this type:
interface SliderChangedDetailType {
  id: string;
  oldValue: number;
  newValue: number;
}

To listen to the components I have code that looks like:

buttonEl.addEventListener( 'myButtonPressed', ( event : CustomEvent ) => {
  const detail = event.detail as ButtonDetailType;
  //now i have access to detail.id
} );

sliderEl.addEventListener( 'mySliderChanging', ( event : CustomEvent ) => {
  const detail = event.detail as SliderChangingDetailType;
  //now i have access to detail.id, detail.value
} );

As I'm making more components, I'm having difficulty remembering all the custom event names that each component can emit, or the detailType that each event generates.

To solve this problem I was hoping to create an object that contains all the information like this:

EVENTS = {
  button: {
    myButtonPressed: 'myButtonPressed',
    detailType: 'ButtonDetailType',
  },
  slider: {
    mySliderChanged': 'mySliderChanged',
    detailTypes: {
     'SliderChangedDetailType',
     'SliderChangingDetailType',
    }
  }
};

With that, I now have an easy way to access all the Event names available for each component with auto-complete helping me along the way as I type:

buttonEl.addEventListener( EVENTS.button. //autocomplete shows me all event names here! YAY!
sliderEl.addEventListener( EVENTS.slider. //autocomplete here too!

The problem that I am having is I don't know how to convert a string to a type. I'd like to be able to type this:

buttonEl.addEventListener( EVENTS.button.myButtonPressed, ( event : CustomEvent ) => {
  const detail = event.detail as EVENTS.button.detailType; // <- invalid: EVENTS.button.detailType is a string not a type!
} );

Is there a way to convert strings to types in TypeScript?


回答1:


You can't really convert strings to types without a mapping. In fact, you really don't want those strings in the first place except for the actual string passed into addEventListener() as the type parameter. It seems like what you actually want is something like namespaces or modules to organize your types.

For example, using namespaces we can get something similar to your EVENTS object, except that instead of referring to just string values, it refers to string values and types:

namespace EVENTS {
  export namespace button {
    export const myButtonPressed = "myButtonPressed";
    export namespace detailType {
      export interface ButtonDetailType {
        id: string;
      }
    }
  }
  export namespace slider {
    export const mySliderChanged = "mySliderChanged";
    export namespace detailTypes {
      export interface SliderChangingDetailType {
        id: string;
        value: number;
      }
      export interface SliderChangedDetailType {
        id: string;
        oldValue: number;
        newValue: number;
      }
    }
  }
}

This should give you the same autocompletes you saw before, plus ones for the types:

buttonEl.addEventListener(EVENTS.button.myButtonPressed, ((event: CustomEvent) => {
  const detail = event.detail as EVENTS.button.detailType.ButtonDetailType;
}) as EventListener);

sliderEl.addEventListener(EVENTS.slider.mySliderChanged, ((event: CustomEvent) => {
  const detail = event.detail as EVENTS.slider.detailTypes.SliderChangedDetailType;
}) as EventListener)

It's up to you if you want to change the level of nesting and naming of things since the namespace makes some things redundant (maybe you want EVENTS.slider.details.SliderChanged instead of EVENTS.slider.detailTypes.SliderChangedDetailType), but the main idea here is the general approach of using namespaces or modules.

Hope that helps; good luck!



来源:https://stackoverflow.com/questions/54133265/typescript-how-to-convert-a-string-to-a-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!