I am trying to emit declarations for types and functions annotated with JSDoc. Those are useful for TypeScript users and generating them from JSDoc means less overhead on our SDK developers.
TypeScript users should get one module called Apify
and from that access our SDK functions.
import {Apify} from "apify";
const envs = Apify.getEnv();
...
This does not happen and the generated index.d.ts
contains multiple modules, one for each JS source file.
My JavaScript library is a single module visible to the client code. Source code is composed of multiple files in src/
directory:
src/index.js
src/actor.js
src/request.js
The index.js
file re-exports functions defined in other files, so they can be accessed by client code running in Node.js.
import { main, getEnv, call, callTask, ... } from './actor';
import Request from './request';
...
/**
* The following section describes all functions and properties provided by the `apify` package...
*
* @module Apify
*/
module.exports = {
main,
getEnv,
...
Request,
...
};
In package.json
, the file build/index.js
is defined as the entry-point (after being transpiled by babel from src/index.js
):
{
"main": "build/index.js",
...
}
My tsconfig.json
is the following:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"lib": [
"es2017",
"dom"
],
"allowJs": true,
"checkJs": false,
"noEmit": false,
"declaration": true,
"emitDeclarationOnly": true,
"strict": false,
"noImplicitThis": true,
"alwaysStrict": true,
"esModuleInterop": true,
"outFile": "types/index.d.ts"
},
"include": [
"src/index.js"
]
}
After running tsc
I get my types/index.d.ts
, with module declarations for each of my JS source file (each of them is inaccessible by the client code) and an empty index
module:
declare module "actor" {
export function getEnv(): Env;
export function main(userFunc: Function): void;
...
}
declare module "request" { ... }
...
declare module "index" {
export {};
}
Use named exports to export a function in TypeScript, e.g. export function sum() {} . The exported function can be imported by using a named import as import {sum} from './another-file' . You can use as many named exports as necessary in a single file.
To re-export values from another file in TypeScript, make sure to export the name exports as export {myFunction, myConstant} from './another-file and the default export as export {default} from './another-file' . The values can be imported from the file that re-exported them.
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).
this issue is because you are using module.exports instead
of export default
change
/**
* The following section describes all functions and properties provided by the `apify` package...
*
* @module Apify
*/
module.exports = {
main,
getEnv,
...
Request,
...
};
to
/**
* The following section describes all functions and properties provided by the `apify` package...
*
* @module Apify
*/
export default {
main,
getEnv,
...
Request,
...
};
then for example lets look at this files
actors.js
module.exports = {
main: () => { console.log("main") },
getEnv: () => { console.log("getEnv") }
}
request.js
module.exports = {
Request: () => { console.log("req") }
}
and index.js
import { main, getEnv } from './actor';
import Request from './request';
/**
* The following section describes all functions and properties provided by the `apify` package...
*
* @module Apify
*/
export default {
main,
getEnv,
Request,
};
types file with module.export
declare module "actor" {
export function main(): void;
export function getEnv(): void;
}
declare module "request" {
export function Request(): void;
}
declare module "index" {
export {};
}
and with export default
declare module "actor" {
export function main(): void;
export function getEnv(): void;
}
declare module "request" {
export function Request(): void;
}
declare module "index" {
namespace _default {
export { main };
export { getEnv };
export { Request };
}
export default _default;
import { main } from "actor";
import { getEnv } from "actor";
import Request from "request";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With