Home > Blockchain >  Return type of function properties in typescript declaration
Return type of function properties in typescript declaration

Time:10-28

I'm trying to fix the Typescript declaration for youtube-dl-exec, which has a default export which is a function with properties. In short, the default export returns a promise, alternatively you can call the exec() method which returns a child process so you can monitor the progress without waiting for the promise to resolve.

The existing declaration works for the default function, but not 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)

What I've come up with so far is this declaration:

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;
}

Now the existence and signature of exec is seen by Typescript, but with the return type of any. I don't think the type import is a problem, indeed even if I change the return type to a primitive string the Typescript compiler still sees the return type of exec as `any.

Since the assignment of the function property almost works, I feel like I'm on the right track, but can't figure out how to specify the return type of this function property.

CodePudding user response:

This in implemented by either using namespace

  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;
}

or merging function type 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;
}

  • Related