打字稿:如何将字符串转换为类型

Posted

技术标签:

【中文标题】打字稿:如何将字符串转换为类型【英文标题】:Typescript: How to convert a string to a type 【发布时间】:2019-06-05 14:14:19 【问题描述】:

我正在创建一堆 Web 组件,每个组件都可以发出自定义事件。作为一个例子,这里有两个简单的例子:

//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;

要收听组件,我的代码如下:

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
 );

随着我制作更多组件,我很难记住每个组件可以发出的所有自定义事件名称,或者每个事件生成的 detailType。

为了解决这个问题,我希望创建一个包含所有信息的对象,如下所示:

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

这样,我现在可以轻松访问每个组件可用的所有事件名称,并在我键入时自动完成帮助我:

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

我遇到的问题是我不知道如何将字符串转换为类型。我希望能够输入以下内容:

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!
 );

有没有办法在 TypeScript 中将字符串转换为类型?

【问题讨论】:

【参考方案1】:

如果没有映射,您无法真正将字符串转换为类型。事实上,除了作为type 参数传递给addEventListener() 的实际字符串之外,您真的不希望首先使用这些字符串。看起来您真正想要的是 namespaces 或 modules 之类的东西来组织您的类型。

例如,使用命名空间,我们可以获得类似于您的EVENTS 对象的东西,除了它不仅仅引用字符串值,而是引用字符串值类型:

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;
      
    
  

这应该会为您提供与之前看到的相同的自动完成功能,以及类型的自动完成功能:

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)

是否要更改事物的嵌套和命名级别取决于您,因为命名空间使某些事物变得多余(也许您想要 EVENTS.slider.details.SliderChanged 而不是 EVENTS.slider.detail<b>Type</b>s.SliderChanged<b>DetailType</b>),但这里的主要思想是一般方法使用命名空间或模块。

希望有所帮助;祝你好运!

【讨论】:

太棒了,这正是我想要的!

以上是关于打字稿:如何将字符串转换为类型的主要内容,如果未能解决你的问题,请参考以下文章

打字稿并将对象转换为字符串

如何将这些对象转换为打字稿中的数组

如何在打字稿中将存储在 Observable<any> 中的值转换为字符串?

将打字稿接口属性类型转换为联合[重复]

在打字稿中将 JSON 转换为字符串数组

如何在打字稿接口/类型中将枚举值类型转换为数组?