内联TypeScript中的类型定义

问题描述

我正在为没有类型定义的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>

这可能对您不起作用。

Playground link to code