在 TypeScript 中内联类型定义

Inline a type definition in 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;
    }
}

这将是理想的,并且在我的想象中表现得像 'Ugly Solution',但遗憾的是不受支持。那么实现这一目标的正确方法是什么?

我认为这目前是不可能的。

有一个未解决的 GitHub 问题,microsoft/TypeScript#25784,要求能够“向下钻取”到 IntelliSense 快速信息,如果实现,可能会也可能不会将联合扩展到它们的成分。

还有 microsoft/TypeScript#40780 要求一个“别名”关键字,它的工作方式与您的建议类似:基本上是一个 类型的宏 ,到时候就被淘汰了任何使用代码的人都会查看它。此问题已作为看起来略有不同的功能的拉取请求草案的副本而关闭。所以这方面的研究似乎很快就消失了。


因此,解决方法:create/declare 一个您想要内联的类型的变量 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