kartikk221 / live-directory

A Simple-To-Use Dynamic Template Content Manager For Webservers
MIT License
12 stars 5 forks source link

Fix(types) : Using export = instead of default #7

Closed Aderinom closed 1 year ago

Aderinom commented 1 year ago

I had problems getting TS to properly import LiveDirectory.

import { LiveDirectory } from 'live-directory';
new LiveDirectory(...)
-> TypeError: live_directory_1.LiveDirectory is not a constructor

After checking the types I saw that the ts exports were different to the actual js exports.

e.g.

ts : export { LiveFile, LiveDirectory };
-> Resulting JS
const live_directory_1 = require("live-directory");
new live_directory_1.LiveDirectory(...);

js : module.exports = LiveDirectory;

I am not aware of any compiler flags which would fix this behaviour. However if there are any this is my tsconfig

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "build",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "importHelpers": true,
    "alwaysStrict": true,
    "sourceMap": true,
    "forceConsistentCasingInFileNames": true,
    "experimentalDecorators": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitAny": false,
    "noImplicitThis": false,
    "strictNullChecks": false,
    "declaration": true,
  },
  "include": ["src/**/*", "src/__tests__/**/*"],
  "exclude": ["node_modules", "build"]
}

Since I assume that this is a problem of the different export types used in .js and d.ts i changed them and made this pr.

Changes :

  1. Replaced default exports with export = Class syntax.
  2. Added the LiveFile type as static member of LiveDirectory.

This allows the types to be imported and used as:

import LiveDirectory from 'live-directory';

const assets = new LiveDirectory(...)
const file = new LiveDirectory.LiveFile(...);

I'm not actually 100% sure if using the export = syntax is the right way to go, since I haven't written types for js modules before.

Furhtermore with export=x it's not possible to export other types, even if they were just declarations.

kartikk221 commented 1 year ago

Your approach worked great on my end, seems like it's the best way to go. Eventually I do plan on re-writing the library in TypeScript which should resolve any of these issues.

Aderinom commented 1 year ago

One thing I just remembered, with your clean JSDocs you can actually easily autogenerate the types.

See : https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html

I tried it on hyper-express and it seems to be working pretty flawlessly.

kartikk221 commented 1 year ago

I see, yeah I ended up writing types manually for hyper-express and all of my other libraries since I learned TypeScript a bit later than when I initially wrote these packages. I'll be rewriting most of these in pure TypeScript soon with future plans for 100% Node.js / Express.js compatibility for hyper-express.