Conversation
This commit introduces TypeScript support to the project by adding type definitions and necessary configuration files. The main changes include: - Addition of `tsconfig.json` to configure the TypeScript compiler. - Creation of type definition files for existing JavaScript modules to enable type checking and IntelliSense. - Updates to `package.json` to include type information and scripts for building types. - Test cases to validate the TypeScript integration and ensure type safety.
📝 WalkthroughWalkthroughAdds JSDoc-based TypeScript typings, a TypeScript build (tsconfig, npm scripts), generated declaration outputs, type-tests, and typing-related documentation and metadata across the codebase; no substantive runtime logic changes except explicit defer async resolution behavior and exported defer API. Changes
Sequence Diagram(s)Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
parser.js (2)
154-166:⚠️ Potential issue | 🟠 Major
icedParsernever returns the parsed config — it only registers the compiler.Compare with
coffeeParser(line 151) which ends withreturn require(filename). This function registers iced-coffee-script but implicitly returnsundefined. The new JSDoc@returns {object | undefined}masks the bug by suggestingundefinedis a valid outcome.Proposed fix
Parser.icedParser = function(filename, content) { Iced = require(ICED_DEP); // coffee-script >= 1.7.0 requires explicit registration for require() to work if (Iced.register) { Iced.register(); } + return require(filename); };
297-308:⚠️ Potential issue | 🟡 MinorJSDoc
@return {number}is inaccurate — this function can returnundefined.Line 307 explicitly returns
undefinedwhen the value isNaN. The return type should reflect this.Proposed fix
- * `@return` {number} - Number value fo the passed variable value + * `@return` {number | undefined} - Number value of the passed variable valuelib/util.js (1)
1137-1141:⚠️ Potential issue | 🟡 Minor
fromEnvironmentparameterenvironmentsshould be marked optional.The implementation checks
if (environments !== undefined)(line 1144), confirming it's optional, but the JSDoc types it as required{string}.Proposed fix
- * `@param` {string} environments the NODE_CONFIG_ENVs you want to load + * `@param` {string} [environments] the NODE_CONFIG_ENVs you want to load
🤖 Fix all issues with AI agents
In `@defer.js`:
- Around line 8-14: The JSDoc for DeferredConfig.prototype.prepare incorrectly
states it returns void; update the comment to return DeferredConfig so callers
(like resolveDeferredConfigs in lib/util.js) can push and later call .resolve()
on the returned instance. Specifically, change the `@returns` annotation for
DeferredConfig.prototype.prepare to reference DeferredConfig (and ensure the
implementation in deferConfig that returns obj still returns the DeferredConfig
instance).
In `@lib/config.js`:
- Around line 17-28: Fix the malformed JSDoc block and the duplicate/conflicting
typedef: add the missing leading space/star to re-align the JSDoc line (so the
entire comment attaches properly), and remove the local duplicate typedef for
LoadOptions in lib/config.js; instead reference the canonical definition from
lib/util.js (or make optionality match by adjusting the property annotations) so
LoadOptions is defined only once—locate the LoadOptions typedef in lib/config.js
and replace it with an import/alias to the LoadOptions typedef in lib/util.js
(or update the property optional markers to match util.js).
In `@lib/util.js`:
- Around line 881-887: Remove the phantom JSDoc param for `{Load} load` from the
JSDoc above the scan function so the documented signature matches the actual
function `scan(additional)`: update the JSDoc to only declare the `additional`
parameter (e.g., `@param {{name: string, config: any}[]=} additional`) and any
relevant description, ensuring the `scan` function and its `additional`
parameter are the only symbols referenced in the comment to prevent TypeScript
from misassigning the `Load` type.
- Around line 339-342: The JSDoc for cloneDeep is malformed: add explicit
parameter names and proper default-value bracket syntax so TypeScript can map
them—change the second and third `@param` entries to use names and defaults like
`@param` {number} [depth=20] Maximum depth and `@param` {boolean} [circular=true]
Handle circular references, and add a fourth `@param` documenting prototype (e.g.
`@param` {object=} prototype Optional prototype for the new object) plus a brief
`@return` description; update the description to reference the cloneDeep function
signature accordingly.
In `@package.json`:
- Around line 93-96: Add a prepublishOnly script that runs the type build so
published packages include declaration files: update package.json scripts to add
a "prepublishOnly" entry that invokes the existing "build:types" (and any other
build step if needed) so the declared "types" and "typesVersions" artifacts are
produced before npm publish; target the "build:types" script name and the
"prepublishOnly" script key in your edit.
- Line 73: Update the TypeScript dependency entry in package.json: replace the
invalid version string "typescript": "5.9.0" with a published version (e.g.,
"5.9.3") so the dependency resolves correctly; edit the existing "typescript"
dependency line in package.json to the valid published version.
🧹 Nitpick comments (4)
parser.js (2)
352-361: Union return typestring[] | numbermakes the API harder to consume in TypeScript.
getFilesOrder()returns the full order array when called without arguments, or an index number when called with a name. This overloaded behavior produces a union return type that forces callers to narrow. Consider whether this could use JSDoc@overloadannotations, or document the two calling conventions more clearly for type consumers.
37-40: Consider using explicit type arguments for theParserFngeneric in return and parameter types for consistency.The
@template [T=any]syntax in the typedef is valid and will emit correctly viatsc --declaration. However, line 335 returnsParserFn | undefinedand line 343 acceptsParserFnwithout type arguments, while the typedef itself defines a generic type. For clarity, explicitly specify the type argument (e.g.,ParserFn<any> | undefinedorParserFn<object>) in these usages to match the generic definition.test/30-types-test.js (1)
19-36: Consider adding atimeouttospawnSyncto prevent the test from hanging.If
tscencounters an issue that causes it to hang, the test runner will block indefinitely.Proposed fix
const result = spawnSync(process.execPath, [tscPath, '-p', tsconfigPath], { cwd: repoRoot, - encoding: 'utf8' + encoding: 'utf8', + timeout: 60_000 });lib/config.js (1)
416-418:loadFileConfigsreturn typeConfigmay be misleading.
newLoad.config(line 432) is a plain object withoutConfigClassprototype methods. Typing it asConfig(alias forConfigClass) implies it has.get(),.has(), etc. Consider typing the return asobjector adding a note that the caller is responsible for callingattachProtoDeep.
This includes updates to the package.json and package-lock.json files to update dependencies, as well as some changes to the defer.js, lib/config.js, and lib/util.js files based on the feedback received about the type information.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@lib/util.js`:
- Line 29: Fix the JSDoc typo for the nodeEnv property: change the description
string "commo-separated" to "comma-separated" in the JSDoc comment that
documents the nodeEnv property (the line mentioning "@property {string[]=}
nodeEnv") so the comment correctly reads "NODE_ENV value or comma-separated
list".
- Around line 979-982: The JSDoc block above the Load class method that returns
ConfigSource[] is misindented; fix the indentation so the opening /**, the
`@returns` {ConfigSource[]}, and the closing */ are aligned with the other JSDoc
blocks in the Load class. Locate the JSDoc immediately preceding the Load class
method (the comment that documents the method returning ConfigSource[]) and
adjust leading spaces to match the class's JSDoc style so the entire block is
visually aligned with the method body.
🧹 Nitpick comments (3)
lib/config.js (2)
92-95: Unbounded@template Tonget()— TypeScript cannot infer it from parameters.Since
propertyis typed asstring, there's no way for TS to inferTfrom JSDoc alone. Callers will getunknownunless they use a cast. This is acceptable for a config library (it's a common pattern in.d.tsfiles where users writeconfig.get<string>('key')), but be aware that JSDoc-based consumers won't benefit from the generic — it will effectively beany/unknown.
404-406:loadFileConfigsreturn typeConfigmay be misleading.The method returns
newLoad.config, which is a plain object ({}), not aConfigClassinstance. Typing it asConfig(alias forConfigClass) could confuse consumers expecting prototype methods likeget()andhas()on the returned object. Consider typing the return asobjectto be more accurate, or documenting that the return is a raw config data object.lib/util.js (1)
7-7:Parsertypedef is duplicated in bothlib/config.js(line 10) andlib/util.js(line 7).Both files define
@typedef {typeof import('./../parser')} Parser. Consider defining it in one place and importing from there to keep a single source of truth, though this is minor given it's a type-only declaration.
| * @property {string} nodeEnv - NODE_ENV value or commo-separated list | ||
| * @property {string} hostName - hostName for host-specific loads | ||
| * @property {string=} configDir - config directory location, absolute or relative to cwd() | ||
| * @property {string[]=} nodeEnv - NODE_ENV value or commo-separated list |
There was a problem hiding this comment.
Typo: "commo-separated" → "comma-separated".
- * `@property` {string[]=} nodeEnv - NODE_ENV value or commo-separated list
+ * `@property` {string[]=} nodeEnv - NODE_ENV value or comma-separated list📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| * @property {string[]=} nodeEnv - NODE_ENV value or commo-separated list | |
| * `@property` {string[]=} nodeEnv - NODE_ENV value or comma-separated list |
🤖 Prompt for AI Agents
In `@lib/util.js` at line 29, Fix the JSDoc typo for the nodeEnv property: change
the description string "commo-separated" to "comma-separated" in the JSDoc
comment that documents the nodeEnv property (the line mentioning "@property
{string[]=} nodeEnv") so the comment correctly reads "NODE_ENV value or
comma-separated list".
| /** | ||
| * <p>Application Configurations</p> | ||
| * | ||
| * <p> | ||
| * The config module exports a singleton object representing all | ||
| * configurations for this application deployment. | ||
| * </p> | ||
| * | ||
| * <p> | ||
| * Application configurations are stored in files within the config directory | ||
| * of your application. The default configuration file is loaded, followed | ||
| * by files specific to the deployment type (development, testing, staging, | ||
| * production, etc.). | ||
| * </p> | ||
| * | ||
| * <p> | ||
| * For example, with the following config/default.yaml file: | ||
| * </p> | ||
| * | ||
| * <pre> | ||
| * ... | ||
| * customer: | ||
| * initialCredit: 500 | ||
| * db: | ||
| * name: customer | ||
| * port: 5984 | ||
| * ... | ||
| * </pre> | ||
| * | ||
| * <p> | ||
| * The following code loads the customer section into the CONFIG variable: | ||
| * <p> | ||
| * | ||
| * <pre> | ||
| * const CONFIG = require('config').customer; | ||
| * ... | ||
| * newCustomer.creditLimit = CONFIG.initialCredit; | ||
| * database.open(CONFIG.db.name, CONFIG.db.port); | ||
| * ... | ||
| * </pre> | ||
| * | ||
| * @module config | ||
| * @class Config | ||
| */ |
There was a problem hiding this comment.
This seemed duplicative of the JSDocs just below, so I removed them. If there is something in here that is important to maintain with the docs below, I'm happy to update it.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@lib/config.js`:
- Around line 404-406: The return type for loadFileConfigs is misleading because
it returns newLoad.config (a plain object from Load) rather than a ConfigClass
instance; either call attachProtoDeep on newLoad.config before returning (so it
becomes a ConfigClass-like object with get/has) or change the declared return
type to a plain object/precise shape (e.g., object or Record<string, any>)
instead of Config/ConfigClass; update the loadFileConfigs implementation or its
type annotation accordingly and ensure references to newLoad.config and
attachProtoDeep are the targets for the change.
🧹 Nitpick comments (1)
lib/config.js (1)
92-94:@template Tonget()won't provide type narrowing without a cast by the caller.The generic
Tis unconstrained and not linked to any input parameter, so TypeScript will inferTasunknownunless the caller explicitly provides a type argument (e.g.,config.get<string>('key')). This is a known limitation of JSDoc-based generics and is acceptable, but worth documenting for consumers or considering a typed overload in the.d.tsfile.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
parser.js (1)
297-308:⚠️ Potential issue | 🟡 Minor
numberParserreturn type should includeundefined.Line 307 returns
undefinedwhen the value isNaN, but the JSDoc on line 303 declares@return {number}. The generated.d.tswill incorrectly tell consumers this always returns anumber.Proposed fix
- * `@return` {number} - Number value fo the passed variable value + * `@return` {number | undefined} - Number value of the passed variable value
🧹 Nitpick comments (3)
package.json (1)
62-77: TypeScript is pinned to an exact version — consider using a caret range.All other devDependencies use range specifiers (
^or~), buttypescriptis pinned to5.9.3. This means contributors won't automatically get patch fixes. Consider^5.9.3for consistency, unless the exact pin is intentional.Proposed change
- "typescript": "5.9.3", + "typescript": "^5.9.3",lib/config.js (1)
92-95: Unconstrained@template Tongetwill infer asunknownin generated declarations.Since there's no way to bind
Tto the config shape from JSDoc alone, the generated.d.tswill type the return asTwhich callers must narrow themselves. This is acceptable but worth noting — consumers will likely need type assertions likeconfig.get<string>('key')or typed wrappers.parser.js (1)
352-361:getFilesOrderreturn type union makes consuming code awkward.
string[] | numberaccurately reflects the overloaded behavior, but this is a pre-existing API design choice. For the generated.d.ts, consumers will need type narrowing on every call. This is fine to leave as-is for now.
The test files were added in a `types` directory in the `test` directory but the `.gitignore` file was setup to ignore those, and I forgot to add them in.
|
Unfortunately this collides with the PR I just landed. But If you want to clean it up I'll try to land it before I merge the other 2 PRs which will again break it. |
|
LGTM @markstos @lorenwest ? |
|
@jdmarshall Just updated with the changes and added in JSDocs for the new files |
This commit introduces TypeScript support to the project by adding type definitions and necessary configuration files. The main changes include:
tsconfig.jsonto configure the TypeScript compiler.package.jsonto include type information and scripts for building types.This helps address #870
Summary by CodeRabbit
New Features
Documentation
Chores
Tests