问题描述
我正在为没有类型定义的jQuery库编写类型定义文件(index.d.ts
)。
该库的方法反复接受相同多类型(string | number | []
)的参数,因此我将其定义为CustomType
:
export type CustomType = string | number | [];
declare global {
interface JQuery<TElement = HTMLElement> {
setFoo(foo: CustomType): this;
setBar(bar: CustomType): this;
}
}
当我现在要在jQuery对象上调用setFoo()
时,(类型IntelliJ的)类型提示表明参数foo: CustomType
是预期的,这在没有查找该类型的情况下对其他开发人员没有帮助像。
相反,我希望看到提示显示foo: string | number | []
的类型。
例如,在C ++中,有一个inline
函数的概念,它基本上告诉编译器将内联函数主体的代码直接放在调用它的块中,而不是调用/跳转到该函数。 。 TypeScript中有类似的东西吗?
如何强制TypeScript内联此CustomType
并使其显示为foo: string | number | []
而不是foo: CustomType
?
丑陋的解决方案
declare global {
interface JQuery<TElement = HTMLElement> {
setFoo(foo: string | number | []): this;
setBar(bar: string | number | []): this;
}
}
一种解决方案是消除CustomType
并使用多类型显式地键入参数,但是由于越来越多的方法使用相同类型而变得不便,因为它不能从可重用性中受益,在我看来,这很丑。
虚构解决方案
export type CustomType = string | number | [];
declare global {
interface JQuery<TElement = HTMLElement> {
setFoo(foo: inline CustomType): this; // <-- note the 'inline' here
setBar(bar: inline CustomType): this;
}
}
这将是理想的,并且在我的想象中,其行为类似于“丑陋的解决方案”,但不幸的是不受支持。那么实现这一目标的正确方法是什么?
解决方法
我认为目前不可能。
有一个公开的GitHub问题,microsoft/TypeScript#25784,要求能够“深入”到IntelliSense快速信息中,如果实施了该信息,则可能会或可能不会将联合扩展为它们的组成部分。
还有一个microsoft/TypeScript#40780,它要求一个“别名”关键字的用法与您所建议的类似:基本上是一个 type宏,在使用代码的任何人都看到时,它就会被消除在它。此问题已作为对外观稍有不同的功能的拉取请求草稿的重复而关闭。因此,这方面的研究似乎很快就结束了。
因此,解决方法:创建/声明要内联的类型的变量x
,并将此类型称为typeof x
。我认为,在呼叫站点,IntelliSense应该将typeof x
解析为扩展类型。我不能保证会一直发生这种情况(编译器如何决定呈现类型信息的细节对我来说有点模糊),但是在我的测试中似乎做到了。例如:
const __Custom: string | number | any[];
interface JQuery<TElement = HTMLElement> {
setFoo(foo: typeof __Custom): this;
setBar(bar: typeof __Custom): this;
}
再后来:
declare const $: JQuery;
$.setBar(""); // IntelliSense says
// setBar(bar: string | number | any[]): JQuery<HTMLElement>
这可能对您不起作用。