如何在Typescript中扩展/覆盖导出的类型

时间:2018-11-24 02:19:04

标签: typescript

我正在使用@fortawesome@fortawesome/react-fontawesome@fortawesome/fontawesome-common-typesIconDefinition定义为

export interface IconLookup {
  prefix: IconPrefix;
  // IconName is defined in the code that will be generated at build time and bundled with this file.
  iconName: IconName;
}

export interface IconDefinition extends IconLookup {
  icon: any[];
}

export type IconProp = IconLookup | /*...*/;

export type IconName = /* a lot of concatenated strings */;

@fortawesome/react-fontawesome定义

export function FontAwesomeIcon(props: Props): JSX.Element;
export interface Props {
    icon: IconProp;
    /* ... */
}

我想添加自己的SVG,并在icon的{​​{1}}属性中使用它们。

<FontAwesomeIcon />

只要import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; type CustomIconName = 'myCustomIcon' /* | ... */; interface CustomIconDefinition extends Pick<IconDefinition, Exclude<keyof IconDefinition, 'iconName'>> { prefix: 'fab', iconName: CustomIconName; } const MyCustomIcon: CustomIconDefinition = /* ... */; export default function() { let icon: any = MyCustomIcon; return <FontAwesomeIcon icon={icon} />; } 的类型为icon,此方法就起作用。

我想删除any并覆盖或扩展CustomIconDefinition的定义,使其包含IconName

我想做类似的事情:

MyCustomIcon

这会导致import { IconName as VanillaIconName } from '@fortawesome/fontawesome-common-types'; declare module "@fortawesome/fontawesome-common-types" { export type IconName = VanillaIconName | MyCustomIcon; } 我怀疑,即使我解决了这个问题,因为Duplicate identifier 'IconName'. index.d.ts(16,13): 'IconName' was also declared here.引入了循环定义,这还会出错。

我还考虑过覆盖IconName = VanillaIconName的定义,但是由于FontAwesomeIcon有很多种类型,所以我对这个定义的理解不高。我想我可以创建自己的icon: IconProp,但这并不理想。

1 个答案:

答案 0 :(得分:1)

2.5 年后我突然想到,虽然 type 扩充声明合并是不可能的,但 interface 声明合并是可能的。

我还没有测试过这个代码,因为我什至不记得我需要它用于哪个项目,但我应该能够增加 Props@fortawesome/react-fontawesome

import { IconProp } from '@fortawesome/fontawesome-common-types';

declare module '@fortaweome/react-fontawesome' {
  export interface Props {
    icon: CustomIconProp;
  }
}

type CustomIconName = 'myCustomIcon' /* | ... */;

interface CustomIconProp extends Omit<IconProp, 'iconName'> {
  iconName: CustomIconName;
}

这并没有解决标题中提出的问题,但确实解决了我遇到的问题。


注意:通过使用 patch-package 覆盖包的声明文件,有一种超级黑客方法可以解决标题带来的问题。遗憾的是,我之前对我必须使用的依赖版本采取了这种方法,但是未来的版本修复了我需要的类型。