在 TypeScript 中内联类型定义

Tob*_*ker 7 inline typescript type-definition

我正在index.d.ts为一个没有类型定义的 jQuery 库编写一个类型定义文件 ( )。
该库的方法重复接受相同多类型(string | number | [])的参数,因此我将其定义为CustomType

export type CustomType = string | number | [];

declare global {
    interface JQuery<TElement = HTMLElement> {
        setFoo(foo: CustomType): this;
        setBar(bar: CustomType): this;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我现在想要调用setFoo()jQuery 对象时,(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;
    }
}
Run Code Online (Sandbox Code Playgroud)

一种解决方案是消除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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将是理想的,在我的想象中,它的行为就像“丑陋的解决方案”,但不幸的是不受支持。那么实现这一目标的正确方法是什么?

jca*_*alz 5

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

有一个开放的 GitHub 问题microsoft/TypeScript#25784,要求能够“深入”到 IntelliSense 快速信息,如果实现的话,可能会也可能不会将联合扩展到其组成部分。

还有microsoft/TypeScript#40780,它要求一个“别名”关键字,其工作原理与您建议的类似:基本上是一个类型宏,当任何使用代码的人查看它时就会被消除。该问题作为草稿拉取请求的重复项而被关闭,该请求看起来略有不同。因此,这方面的研究似乎很快就消失了。


因此,解决方法:创建/声明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;
}
Run Code Online (Sandbox Code Playgroud)

然后后来:

declare const $: JQuery;
$.setBar(""); // IntelliSense says 
// setBar(bar: string | number | any[]): JQuery<HTMLElement>
Run Code Online (Sandbox Code Playgroud)

这可能适合你,也可能不适合你。

Playground 代码链接