Embedding a data type definition directly within a TypeScript code block

Currently, I am in the process of creating a type definition file called index.d.ts for a jQuery library that does not have its own type definition.
The functions within this library repeatedly accept parameters with multi-types (string | number | []), so I have defined a custom type called CustomType:

export type CustomType = string | number | [];

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

When I try to call the setFoo() function on a jQuery object, the type hinting in IntelliJ indicates that a parameter foo: CustomType is expected. This can be confusing for other developers without prior knowledge of what this type represents.
Instead, I would prefer the type hinting to display foo: string | number | [].

In C++, there exists the concept of an inline function, which instructs the compiler to insert the code directly at the calling location rather than jumping to the function's body. Is there a similar feature in TypeScript?

Is there a way to make TypeScript display foo: string | number | [] instead of foo: CustomType through some form of inlining?

Potential Solution

declare global {
    interface JQuery<TElement = HTMLElement> {
        setFoo(foo: string | number | []): this;
        setBar(bar: string | number | []): this;
    }
}

An option could be to remove the CustomType and explicitly specify parameter types as their corresponding multi-types. However, this approach becomes cumbersome when dealing with numerous methods that share the same type, lacking reusability while appearing unappealing.

Desired Solution

export type CustomType = string | number | [];

declare global {
    interface JQuery<TElement = HTMLElement> {
        setFoo(foo: inline CustomType): this; // <-- 'inline' notation
        setBar(bar: inline CustomType): this;
    }
}

This theoretical solution would mirror the behavior of the previous "Potential Solution," but sadly, it is not supported. What would be the correct approach to achieve this desired outcome?

Answer №1

Currently, it seems that this functionality is not available.

An issue on GitHub by microsoft/TypeScript (#25784) suggests the possibility of delving deeper into IntelliSense quick info to potentially expand unions into their elements, although it remains unresolved at present.

Another issue with microsoft/TypeScript (#40780) proposes an "alias" keyword similar to a type macro concept, but it was closed as a duplicate and further development appears to have halted swiftly.


As a workaround, consider creating or declaring a variable x with the desired type and reference it as typeof x. This should, in theory, prompt IntelliSense to display the expanded type at call sites. While there are no guarantees due to ambiguous compiler behaviors, testing has shown promising results.

const __Custom: string | number | any[];

interface JQuery<TElement = HTMLElement> {
  setFoo(foo: typeof __Custom): this;
  setBar(bar: typeof __Custom): this;
}

For example:

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

This method may or may not suit your specific needs.

Click here for Playground link

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular encountered an error when trying to access the property "fruits" of an undefined object

When working with Angular, I encountered an issue where I received the error message "cannot read property 'fruits' of undefined." Within my class definition, I have included the following: export class MyClass implements OnInit { fruits: any[] ...

Tips for effectively generating a JSON object array in Typescript

Currently, I'm attempting to construct an array of JSON objects using TypeScript. Here is my current method: const queryMutations: any = _.uniq(_.map(mutationData.result, function (mutation: Mutation) { if (mutation && mutation.gene) { co ...

Using RxJS with Angular to intercept the valueChanges of a FormControl prior to subscribing

I decided to create a new observable using the values emitted by the FormControls.valueChanges observable. This creation of the observable takes place within the ngOnInit method in the following manner: ngOnInit(): void { this.myObservable$ = combine ...

The ngAfterViewInit lifecycle hook does not get triggered when placed within ng-content

The ngAfterViewInit lifecycle hook isn't triggered for a Component that is transcluded into another component using <ng-content>, as shown below: <app-container [showContent]="showContentContainer"> <app-input></app-input> ...

Ways to avoid using a specific type in TypeScript

Imagine having a class that wraps around a value like this: class Data<T> { constructor(public val: T){} set(newVal: T) { this.val = newVal; } } const a = new Data('hello'); a.set('world'); // typeof a --> Primitiv ...

Enclose this within Stencil.js components

Is there a more efficient way to utilize a nested "this" in a Stencil.js component? Currently, I find myself following this approach: render() { let thisNested = this; return <Host> {this.images ? this.imagesArray.map(fu ...

Visual Studio Code is encountering issues when trying to start a Node application

I am in the process of setting up a workflow for an express app using TypeScript, Visual Studio Code, and gulp. Here is the structure of my project: src/ <-- source files Start.ts Server.ts models/ Contact.ts Organization.ts bin/ <- ...

The reason why Type zzz cannot be assigned to type (zzz & NgIterable<xxx>) | undefined | null

Why am I receiving the message in Angular 9 that says: Type Items is not assignable to type (Items & NgIterable) | undefined | null? Despite the fact that the model is correct and there are no errors in the data, I still encounter this TypeScript warn ...

Here's how to use the useState hook directly in your React components without

Currently, I am using the code snippet below to import useState: import * as React from 'react' import {useState} from 'react' I wanted to see if there is a way to condense this into one line, so I attempted the following: import * a ...

When I bring in a component from my personal library, it will assign the type "any" to it

I'm facing an issue when trying to import a component from my own library. The component within the library is actually sourced from another one (so I import the component, customize it, and then export the customized version). However, upon importi ...

Is it possible to swap out the Firestore module `doc` with the `document` module

I enjoy using the Firebase version 9 modules, however, I find that doc is not to my liking. It would be better if it were document, similar to how collection is not shortened to col. The following code does not function as expected: import { doc, collecti ...

Develop an item with a function that takes an input of the identical type as a variable within the item itself

I am facing a challenge with managing an array of objects that represent commands for my game. Each object includes an input field to define the types of arguments expected by the command. The purpose of this setup is to enable validation on the arguments ...

A better choice than Java's <? super SomeType> in Typescript

Is there a scenario in which one of the generic parameters used to create an instance of my class should be a superclass of another class? In Java, this is easily achievable using <? super SomeType>. What would be the equivalent in TypeScript? ...

Utilize Charts.js to transform negative values into graphical representations

I am struggling with transforming the expense data into a positive number in my bar chart. The data consists of both income and expenses, and I want to display them as positive numbers for easier comparison. I attempted using Math.abs(this.barData[1]) in n ...

Updating from version 1.8.10 to 2.9.2 and encountering a build error in version 4.6.4

I currently have an angular application that is using typescript version 1.8.10 and everything is running smoothly. However, I am interested in upgrading the typescript version to 2.9.2. After making this change in my package.json file and running npm inst ...

What is the best way to switch to a different screen in a React Native application?

I've recently dived into the world of React Native and embarked on a new project. The initial screen that greets users upon launching the app is the "welcome screen," complete with a prominent 'continue' button. Ideally, clicking this button ...

The CLI feature is not compatible with NextJS Drizzle-Kit

I'm currently utilizing the drizzle auth template and attempting to customize it for Role Based Authentication. I've made adjustments in the db.ts file to incorporate roles. import { drizzle } from 'drizzle-orm/postgres-js'; import { pg ...

Filtering Deno tests by filename: A step-by-step guide

How can I selectively run Deno tests based on their filenames? Consider the following test files: number_1_test.ts number_2_test.ts string_test.ts If I want to only run tests with filenames starting with number*, I am unable to use either of these comma ...

How can I retrieve the number of events remaining after removing one in Protractor's end-to-end automation?

I am in need of testing the removal of an event and confirming that it has been successfully removed. Since these events are not unique and can vary in number during testing, I believe using a count would be the most suitable approach. This is all new to ...

Exploring the world of external libraries with NPM in Angular 2 using TypeScript

I am currently utilizing Ionic2 (Browserify) and Typescript with NPM. I have been exploring how typescript compiles the code into bundles and what gets included in the bundle. I noticed that some of my node require files are referenced automatically, whil ...