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