【问题标题】:How to create a globally available interface/type in TypeScript?如何在 TypeScript 中创建全局可用的接口/类型?
【发布时间】:2021-03-23 02:12:08
【问题描述】:

我正在使用 Preact 和 TypeScript 创建一个组件库。我有一个图标组件,可以像这样使用:

<SVGIcon name='camera' width={16} height={24} />

并且,它被实现为:

export interface SVGIconProps {
  class?: string;
  width?: string;
  height?: string;
  name: string;
};

export function SVGIcon(props: SVGIconProps) { /* return svg; */ }

为了为图书馆用户提供更好的智能感知,我想将 name 道具的类型缩小到一组有限的字符串文字(基本上只显示允许的图标名称)。当然,我可以使用库提供的字符串文字;但是,用户也可以使用如下注册函数动态注册自己的附加图标集:

registerIcon('icon-name', jsxFunctionReturningSVGFragment);

registerIcon 函数将图标及其 JSX 函数添加到内部缓存(ES Map 的实例)。

这个问题是,考虑到图书馆用户在使用图书馆时可以添加一个或多个图标这一事实,我如何才能保留窄输入并为图书馆用户提供自动完成/智能感知?

是否可以在库级别声明一个虚拟接口/类型,例如 MyLibIconSet,然后库的用户应该在使用库之前在他的代码库中覆盖它?类似于我们如何进行声明合并或使用全局扩充来修补缺失类型?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我认为这可以通过declaration merging 实现。

    您可以定义一个接口,为每个可能的图标都有一个成员。在这种情况下,类型可以是您喜欢的任何类型:

    export interface SVGPossibleIcons {
      thumbsUp: string;
      thumbsDown: string;
      roflSmiley: string;
    }
    

    然后你可以像这样定义你的道具:

    export interface SVGIconProps {
      class?: string;
      width?: string;
      height?: string;
      name: keyof SVGPossibleIcons;
    }
    

    然后,图书馆的用户必须使用他/她自己的图标来扩展该界面,如下所示:

    declare module "YourSVGModuleName" {
        export interface SVGPossibleIcons {
            anotherCustomSmiley: string;
        }
    }
    

    【讨论】:

    • 这是一个聪明的解决方案。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 2020-05-20
    • 2020-07-10
    • 2016-12-30
    相关资源
    最近更新 更多