Typescript declaration specifies the return type of function properties

I am currently working on fixing the Typescript declaration for youtube-dl-exec. This library has a default export that is a function with properties. Essentially, the default export returns a promise, but alternatively, you can use the exec() method which returns a child process allowing you to monitor progress without waiting for the promise to resolve.

The current declaration functions correctly for the default function, but not for any of the properties:

import ytdl from 'youtube-dl-exec';
const p = ytdl('https://example.com'); // p is Promise<YtResponse>
const r = ytdl.exec('https://example.com'); // r should be ExecaChildProcess
// ^ property exec does not exist … ts(2339)

My proposed declaration so far is as follows:

declare module 'youtube-dl-exec' {
  type ExecaChildProcess = import('execa').ExecaChildProcess;

  const youtubeDl = (url: string, flags?: YtFlags, options?: Options<string>) => Promise<YtResponse>;
  youtubeDl.exec = (url: string, flags?: YtFlags, options?: Options<string>) => ExecaChildProcess;

  export default youtubeDl;
}

Currently, Typescript recognizes the existence and signature of exec, but assigns the return type as 'any'. Even if I change the return type to a primitive string, the Typescript compiler still identifies the return type of exec as 'any.'

Despite getting close with assigning the function property, I am struggling to specify the return type of this function property.

Answer №1

To achieve this, one can implement it by utilizing namespaces

  type ExecaChildProcess = import('execa').ExecaChildProcess;

  declare const youtubeDl: (url: string, flags?: YtFlags, options?: Options<string>) => Promise<YtResponse>;
  declare namespace youtubeDl {
    export const exec: (url: string, flags?: YtFlags, options?: Options<string>) => ExecaChildProcess;
  }
  export default youtubeDl;
}

Alternatively, the function type can be merged with object type

declare module 'youtube-dl-exec' {
  type ExecaChildProcess = import('execa').ExecaChildProcess;

  declare const youtubeDl: (
    (url: string, flags?: YtFlags, options?: Options<string>) => Promise<YtResponse>
  ) & {
    exec: (url: string, flags?: YtFlags, options?: Options<string>) => ExecaChildProcess;
  }

  export default youtubeDl;
}

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

Manipulating a DOM element in Angular 2 to alter its class attribute

I am a beginner in angular2. Here is my code: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'main', template: ` <div class="current"> </div> ` }) export class MainComponent impl ...

Is your Typescript struggling to infer types correctly?

I created a function that converts an Array into a Map: function toMap<T,TKey,TElement>(items: Array<T>, keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement ): Map<TKey,TElement> { var ma ...

jQuery AJAX event handlers failing to trigger

It's driving me crazy! I've been using jquery's ajax for years, and I can't seem to figure out why the success, error, and complete events won't fire. The syntax is correct, the service it's calling works fine, but nothing hap ...

When attempting to debug JavaScript in Edge with Visual Studio Code, an error message stating 'Failed to load source map for chrome-error...' was encountered

Attempting to troubleshoot JavaScript code in Visual Studio Code is resulting in an error: Could not read source map for chrome-error://chromewebdata/: Unexpected 503 response from chrome-error://chromewebdata/edge-elixir-neterror.rollup.js.map: Unsupporte ...

Using " " to split a name into two lines is not being recognized

My issue involves the display of tab names in two lines within multiple tabs. You can view the demonstration here. I attempted to use the \n character while setting the tab name but it was not recognized. Any suggestions on how to achieve this? Here ...

Uncovering the characteristics of a GeoJSON data layer within Google Maps V3

Is there a way to access the properties of the data layer itself when loading a geoJSON file into a Google Map? I understand how to access the individual properties like posts_here, but I'm interested in obtaining the properties for the layer as a wh ...

Is there a more efficient method for replacing all attributes on cloned elements?

While this code does the job, I can't help but feel like it's a bit outdated. I'm not very experienced with JS/JQuery and only use them when necessary. My approach involves cloning an element and then replacing all of its attributes with on ...

I am converting a class component to a functional component within a React-Redux-Firebase project

I am currently in the process of rebuilding this component. Check out the updated code here Also, take a look at the project actions script here However, I'm facing an issue with rewriting mapStateToProps and mapDispatchToProps functions. The error ...

Combining GET and POST requests in ExpressJS on a single route

As I work on setting up a questionnaire in Express JS with EJS as the renderer, I have already created individual pages for each question. These pages are accessible through static links using the app.get('/question/:number?', routes.questions) f ...

Deleting the clone <div> while ensuring the main <div> is kept clear of any remaining data

Initially: https://i.sstatic.net/SLG7O.png After adding a new row and then removing it. https://i.sstatic.net/FegjK.png Why is this happening? When I set val(""), the textbox should have no value. What mistake did I make in my code? Please assist. Her ...

Leveraging CDK Context Variables in C# Lambda Initialization Code

I have a .NET Lambda function written in C# that is implemented as a .NET Minimal API according to the guidance provided here. To define AWS resources, I am utilizing CDK (TypeScript). Within my build pipeline, there is shell scripting involved to supply ...

Develop your own personalized Angular schematics that produces a file that begins with an underscore

Having trouble with custom Angular schematics file naming. I'm trying to create a theme SCSS file that starts with an underscore followed by a double underscore as a delimiter. For instance, I want the file name to be _mouse-theme.scss, using the nam ...

`The Art of Curved Arrows in sigjma.js, typescript, and npm`

I have encountered an issue while trying to draw curved arrows in sigma.js within my TypeScript npm project. The error occurs on the browser/client-side: Uncaught TypeError: Cannot read properties of undefined (reading 'process') at Sigma.pro ...

What is the best way to handle multiple promises when loading a state in Angular?

When loading the /home state, I need to retrieve all users from the database in order to customize the home controller and view based on the logged-in user. Currently, in the :resolve section of the state configuration, I am fetching all 'posts' ...

Making an API request using jQuery

I am currently working on creating a .js file that will send data to an external API, wait for a response, and then interpret the results. The external API I am using is XML-based and requires an HTTPS Post request with the XML content in the body (content ...

There is an absence of the 'Access-Control-Allow-Origin' header on the requested resource despite its existence

Currently, I am working on developing an application using Django and Phonegap. While attempting to send an Ajax Request with the following function: <script> $.ajax({ url: "http://192.168.0.101/commerce/pro ...

When using Vue.js, you may encounter an error message stating that the `document.title` type of 'undefined' cannot be assigned to type 'string' in Typescript

I'm trying to use beforeEnter with Vue Router, but I encountered an error: TS2322: Type 'string | symbol | null | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string&apo ...

Tallying discarded objects post removal from drop zone

Is there a way to accurately count dropped items within a dropped area? I have created an example that seems to be working fine but with one minor issue. When I begin removing items, the count does not include the first item and only starts decreasing afte ...

Tips on using Bootstrap 4 containers within a container-fluid and ensuring text stays within a container at all times

What is the best way to incorporate a Bootstrap 4 container within a container-fluid? how can we ensure that text is always contained within the blue section? ...

Retrieving information in JSON format

My goal is to retrieve data from the info.php file in order to utilize it in my project. This is what the content of info.php looks like: <?php $dbh = new PDO('mysql:host=localhost;dbname=csgo', 'root', ''); $sth = $dbh ...