Migrate codebase to Typescript - #213
Conversation
|
@Michiel-VandeVelde This PR does not seem to cover the whole codebase? Specifically, the tests are not converted to TS? |
|
@Michiel-VandeVelde something seems of about the changes in this PR and you have conflicts. Likely because the initial commit of your branch is not the same as the one in the base you target. |
bfcdbd6 to
15b049e
Compare
Renames all lib/index source under packages/core to .ts, with a new packages/core/lib/types.ts holding shared interfaces (Query, DatasourceOptions, ControllerOptions, ViewSettings, LdfRequest/ LdfResponse, RenderDone, WorkerConfig, RouterRequest) used throughout the package. Converted bottom-up (Util/UrlData, datasources, views, controllers, routers, then the server/worker/CLI orchestration and index.ts), reusing real classes as types where possible instead of parallel duplicate interfaces (e.g. DatasourceRegistry = Record<string, Datasource>). core is first because every other package in the monorepo depends on it. Also extends .eslintrc/.gitignore/.eslintignore and adds a few more @types/* devDependencies the conversion needed. Verified: typecheck, build, lint, and all 597 tests pass.
Converts all 6 datasource packages (composite, hdt, jsonld, n3, rdfa, sparql) to TypeScript, each importing @ldf/core's types via deep path (@ldf/core/lib/types, @ldf/core/lib/datasources/Datasource) rather than the barrel index, since the barrel only re-exports runtime values. Two recurring type frictions handled pragmatically: lru-cache v5 (the actual declared dependency) has no bundled types and the monorepo's hoisted root lru-cache is an incompatible newer major, so it's pulled in untyped with a small hand-written structural type instead of an @types/* package; and rdf-js vs @rdfjs/types (used by hdt and jsonld-streaming-serializer) are structurally close but not always assignable, needing a narrow `as any` at those boundaries. Preserved as-is per the type-only philosophy: CompositeDatasource's _getDatasourceInfo passes 7 arguments to a 6-param inner function, so hasExactCount on the first call actually receives the callback itself (truthy, so it "works" by accident) — now called out with a comment instead of being silently typed away. Verified: typecheck, build, lint, and all 597 tests pass.
_baseUrl was typed Record<string, any> — replaced with Record<keyof Url, string | boolean | undefined>, matching what lodash's mapValues actually produces from url.parse()'s result (Partial<Url> doesn't typecheck: mapValues collapses the callback's return type to one shared type across all keys, and slashes being the only boolean field means the real union is string | boolean | undefined, not per-field string | null). Replaced the options.views as ViewCollection cast (and the `as any` it forced on the ViewCollection fallback constructor call) with a proper type guard, isViewCollection(). It preserves the original's exact duck-typing check (options.views && options.views.matchView) rather than switching to `instanceof`, which would reject any ViewCollection-like object that isn't a literal instance (e.g. test doubles) — a behavior change, not just a typing one. Verified: typecheck, build, lint, and all 597 tests pass.
parsedUrl was loosely typed, which forced an `as any` at its one real consumer (DereferenceController's url.format call). Typing it as Node's UrlObject (what Controller.handleRequest actually builds it into, from url.parse() merged with a few URL-shaped fallbacks) lets that call drop the cast entirely in favor of `!` — the same "trust it's been set by now" assumption the original JS already made unguarded. The imprecision didn't disappear, it just moved to where it actually originates: Controller.ts's _baseUrl is built via lodash's mapValues, which shares one return type across all keys, so fields like `auth` end up typed string | boolean | undefined instead of the real string | null | undefined even though they can only hold strings. That needed one narrow, commented `as UrlObject` cast at the parsedUrl assignment site, replacing a blanket-typed field with an explained cast at its actual source. Verified: typecheck, build, lint, and all 597 tests pass.
…ator The two early-return branches in Datasource.select() don't actually return a usable iterator: `onError && onError(...)` evaluates to onError's void return (or undefined if it wasn't given), not an AsyncIterator<Quad> — a pre-existing gap in the original JS, preserved as-is with a comment now explaining it instead of a blank `as any`. Needed explicit parens around the whole `onError && onError(...)` expression before casting: `as` binds tighter than `&&`, so casting just the right-hand onError(...) call left the falsy-onError branch's `undefined` uncast, which typechecks against `any` (a union with `any` collapses to `any`) but not against `unknown` (which doesn't). Verified: typecheck, build, lint, and all 597 tests pass.
…e.ts Datasource.supportedFeatures is a Record<string, boolean> built dynamically per-subclass from an arbitrary supportedFeatureList, so a query's features genuinely isn't limited to the 6 named keys — QueryFeatures having an index signature reflects that accurately rather than just working around the for-in loop's generic string key. Removes the `as Record<string, boolean | undefined>` cast in supportsQuery() entirely; purely additive to the interface, no other callers affected. Verified: typecheck, build, lint, and all 597 tests pass.
Retyping these files by hand instead of editing in place silently collapsed several instances of deliberate multi-space alignment from the original JS (e.g. aligning `=` across a multi-declaration `let` block, or padding before `&&` to line up near-identical consecutive lines). Functionally identical either way, but it inflated the diffs with changed lines that weren't actually changed. Verified against the original .js sources line-by-line (not just the two files flagged) to confirm no other such diffs remain. Re-checked: typecheck, build, lint, and all 597 tests pass.
Every as any in this file except one turned out to be unneeded — verified by removing each individually and rechecking: all 5 N3.Writer.addQuad() calls, the N3.Writer constructor, both JsonLdSerializer.write() calls, JsonLdSerializer.pipe(), the JsonLdSerializer constructor, and the settings.prefixes indexing all typecheck cleanly without a cast. These were defensive casts carried over from genuine rdf-js-vs-@rdfjs/types mismatches elsewhere in the conversion (hdt, jsonld-streaming-serializer's stream boundary) that didn't actually apply here. The one real duck-type — extension._generateRdf — now uses a type guard instead of a blind cast, same pattern as Controller.ts's isViewCollection: preserves the original's exact truthy check (extension._generateRdf), not instanceof or typeof === 'function'. Only one `any` remains in the file: context: Record<string, any> in _createJsonLdWriter, a legitimate type (JSON-LD context values can be strings or nested objects), not a cast. Verified: typecheck, build, lint, and all 597 tests pass.
Same approach as the RdfView.ts pass: remove each cast individually, recheck, keep only what's actually necessary. Removed as unnecessary: ViewCollection.ts's negotiate.choose cast, JsonLdDatasource.ts/RdfaDatasource.ts's parser constructor + .import() casts, N3Datasource.ts/SparqlDatasource.ts's constructor casts, LinkedDataFragmentsServer.ts's response.end.bind cast. Tightened from any to a real type: LinkedDataFragmentsServerWorker.ts's accesslogger params (LdfRequest/LdfResponse), readHttpsOption's any (unknown), Util.ts's error variable (Error), SparqlDatasource.ts's _convertLiteral param (Literal from rdf-js), CompositeDatasource.ts's exact local (inferred boolean), ExternalHdtDatasource.ts's parser (real Parser<Quad>, casting only the two actual gaps individually instead of the whole variable). CliRunner.ts's ComponentsManager.build() options cast couldn't be dropped, but got more precise: cast to the real IComponentsManagerBuilderOptions<LinkedDataFragmentsServerWorker> instead of any, since the actual gap is mainModulePath not being statically guaranteed on the spread properties bag. Confirmed necessary and left alone: the for-in prototype-copy pattern in LinkedDataFragmentsServer.ts, protected cross-instance access (_config, _graph, _last/_first), _push calls (protected on asynciterator's BufferedIterator), the n3/hdt/@rdfjs-types boundary mismatches, and the two intentionally-preserved pre-existing bugs (findRecursive's arg count, the parseInt(match-array) coercion). Verified: typecheck, build, lint, and all 597 tests pass.
Was (...args: any[]) => any. Now RequestAPI<Request, CoreOptions, RequiredUriUrl> — the exact generic instantiation the request package's own default export uses. Compiles clean against every call site (Datasource._fetch, SparqlDatasource's two call sites) with no further any needed. Verified: typecheck, build, lint, and all 597 tests pass.
RouterRequest.url.query/headers -> real ParsedUrlQuery/IncomingHttpHeaders
instead of Record<string, any>, which surfaced a real gap: PageRouter's
local `page` var needed widening to include string[] (repeated query
params are legitimately arrays, not just strings).
WorkerConfig.routers -> unknown[], WorkerConfig.accesslogger -> the
real (request: LdfRequest, response: LdfResponse) => void signature.
LinkedDataFragmentsServer.ts: ssl -> https.ServerOptions & { keys?: any },
_sockets -> Record<string, net.Socket>. Datasource.ts's _fetch stream
local -> EventEmitter (was any).
Tried and reverted: _fetch's options param (the real RequiredUriUrl is
a union on .url/.uri that doesn't match how this codebase always uses
.url) and DatasourceOptions.request (forcing the full RequestAPI
interface onto what's meant to be a flexible user-override point would
be over-restrictive).
HtmlView.ts: dropped one redundant Record<string, any> annotation
where plain inference already gave the same result.
Verified: typecheck, build, lint, and all 597 tests pass.
…/_last TS types `new SomeClass()` as SomeClass regardless of what the constructor body actually returns, so external callers of `new LinkedDataFragmentsServer(...)` were seeing none of LdfHttpServer's members. Fixed at the export boundary (a LinkedDataFragmentsServerConstructor cast on `export =`) rather than rewriting the class into a factory function, which would've renamed the export and risked breaking Components.js's `new`-based instantiation. This also let the worker's own redundant cast come out — `new LinkedDataFragmentsServer(config)` now infers correctly. Added _first?/_last? to the base Controller class. Verified this is a genuine shared framework convention, not one controller's private detail: feature-memento's TimegateController (not yet converted) also sets _first. Removes NotFoundController's redundant re-declaration and both any casts in LinkedDataFragmentsServerWorker.ts. Replaced two `as unknown as string` casts (SparqlDatasource.ts, ExternalHdtDatasource.ts) with String(limit)/String(offset) — same output as the original's implicit coercion (Array.join and child_process.spawn both stringify anyway), without lying to the type checker about what's actually in the array. Verified: typecheck, build, lint, and all 597 tests pass.
Same conventions as core and datasource-*: export =/import = require() throughout, cross-package types via @ldf/core's compiled declarations. feature-webid: preserves the existing broken-at-runtime state as-is (lru-cache and N3.Parser both invoked without `new`, cert subject property access that doesn't match the real PeerCertificate shape, predicate comparisons against string literals that can never match). Typing the lru-cache factory correctly removed two any casts outright. feature-memento: TimegateController.ts uses the same namespace-merge pattern as LinkedDataFragmentsServer.ts to share several interfaces via export =. Narrowing toDate()'s signature surfaced a real latent bug in its fallback branch (a string[] can flow through mistyped as Date) — documented with a single as-cast at that exact spot rather than fixed. mementoUrl/originalUrl/acceptDatetime stay any: each is genuinely reassigned across incompatible types within its function. feature-summary: straightforward conversion; two whitespace deviations from the original found and corrected. Verified: typecheck, build, lint, and all 597 tests pass.
Same conventions as the other packages. Added a Router interface
(extractQueryParams) local to QuadPatternFragmentsController.ts, and
reused Controller itself as the type for controller extensions (its
public handleRequest signature is exactly what the extension loop
calls). Query gains an optional patternString field in @ldf/core's
types.ts, populated by the controller and read back by the RDF view.
Typed settings.results as the real AsyncIterator<Quad> it always is
at runtime (rather than settings' own ambient `any`), and its
'metadata' property as the {totalCount, hasExactCount} shape every
datasource implementation actually sets — matching the precedent in
CompositeDatasource.ts rather than falling back to any.
subject/predicate/object/graph in _createPatternString, and
hasTriplePattern/hasQuadPattern in QuadPatternRouter, stay any: each
is reused across a Term and a formatted string within the same
variable, the same pattern already confirmed necessary in
TimegateController's mementoUrl/originalUrl.
Verified: typecheck, build, lint, and all 597 tests pass.
Enables @typescript-eslint/recommended-requiring-type-checking,
matching comunica's own eslint setup. Tuned three rules for noise
specific to this codebase: prefer-const off (let is the pervasive
style throughout), restrict-plus-operands with allowNumberAndString
(plain 'text ' + number is safe and everywhere here), unbound-method
off (every hit is a destructured DataFactory method or lodash's
_.noop, none of which use `this`).
Fixed all resulting findings across core and every package by
replacing `as any` with `as unknown as <real shape>` at each protected/
internal-API access point, and giving several loosely-typed view
helper params real types (AsyncIterator<Quad>, {totalCount,
hasExactCount}, a FragmentInfo/DatasourceInfo pair in
QuadPatternFragmentsRdfView.ts that dropped that file from 63 findings
to 0). Genuine Term/undefined/Error-into-string concatenations got
narrow casts at their exact site instead.
Follow-up pass, since several of those casts could be real types
instead of asserted ones:
- Datasource._graph and LinkedDataFragmentsServerWorker._config
dropped `protected` (compile-time-only change, no runtime effect),
removing the cast at their two call sites entirely.
- LinkedDataFragmentsServer's three prototype methods now use
`declare` class members instead of casting the prototype to a
Pick<...> type at each assignment site. `declare` emits no code, so
the actual `.prototype.x = function(){}` assignments (still required
for the for...in enumerability the constructor relies on) remain the
only real implementation.
- n3's Parser gets its undocumented `_prefixes` and static
`_resetBlankNodePrefix` declaration-merged into its own types
(types/n3-augment.d.ts, confirmed against n3's actual source), so
every access is now a normal checked property read instead of a
local cast repeated per call site.
Confirmed (empirically, via a throwaway augmentation) that
BufferedIterator._push can't be fixed the same way: declaration
merging can add the type, but asynciterator's own `protected` still
blocks access at every call site. Its 5 casts stay as the only way to
call a genuinely protected method from outside its class hierarchy.
Verified: typecheck, build, lint (0 problems), and all 597 tests pass.
A codebase-wide sweep of every postfix `!` assertion, applying the same rigor as the query.limit! fix: for each one, trace whether the value is actually guaranteed non-null, or whether the original JS tolerated it being missing. Replaced with `as unknown as X` (matches the Term-reuse cast pattern) everywhere the original JS gracefully degrades rather than crashes, which `!` was misrepresenting as a guarantee: - PageRouter's config.pageSize! (the code calls isFinite() on it, which only makes sense if it might not be a valid number) - HdtDatasource/ExternalHdtDatasource's query.limit! (same shape as the QuadPatternFragmentsRdfView.ts fix — NaN-comparison, no crash) - TimegateController's version.datasourceId! (undefined as an object key just becomes the literal key "undefined") - SparqlDatasource's four remaining _encodeObject(...)! calls on general Term inputs (push/join or string-concat both tolerate null) Eliminated the assertion entirely in RdfView.ts: `declare dataFactory: DataFactory` on the class replaces three separate this.dataFactory! reads. View's own dataFactory is optional only because HtmlView doesn't need one — every RdfView subclass does. That fix cascaded to QuadPatternFragmentsRdfView-Summary.ts, where four more this.dataFactory! reads had become genuinely unnecessary once the base type was corrected. Confirmed and left alone: assertions backed by a real invariant, either provable by construction (regexes that structurally always match, like /[^;,]*/ and /^(?:([a-z]+):)?/) or enforced by a single controlled call path in our own code (request.url/parsedUrl, always set before any _handleRequest override can run; ErrorController's response.error, set at its one and only call site immediately before use). Not fixed, flagged instead: WebIDControllerExtension's settings.urlData!.protocol and IndexDatasource's delete this._datasources!['/'] both depend on deployment config supplying a value, same as PageRouter, but without a graceful fallback — if wrong, they throw. A cast wouldn't reduce that risk, only relabel it; a real fix means a runtime guard, which is a behavior change, not a typing one. Verified: typecheck, build, lint (0 problems), and all 597 tests pass.
Both of these depended on deployment config supplying a value, with
no graceful degradation if it didn't — unlike every other case from
the audit, a wrong assumption here would throw, not silently produce
a slightly-wrong result. Casting would only have relabeled that risk,
not reduced it, so these get real fallbacks instead:
- WebIDControllerExtension: settings.urlData!.protocol now defaults
via `settings.urlData || new UrlData()`, the same fallback pattern
Controller's own constructor already uses for this exact field.
With no urlData configured, protocol defaults to 'http', so the
existing `_protocol !== 'https'` gate quietly skips WebID
enforcement instead of crashing Components.js instantiation.
- IndexDatasource: options.datasources now falls back to `{}` via the
`x || {}` idiom already used throughout this codebase, so
_datasources is genuinely an object by the time it's deleted from.
The field's own type stays optional (_datasources?), since
_getAllQuads deliberately deletes it later to free memory once
quads are generated — it's meant to go back to undefined over the
object's lifetime.
Verified: typecheck, build, lint (0 problems), and all 597 tests pass.
The ! audit fix repeated the same as unknown as number cast three times on one line — cast once into a local instead.
…t could be Adds no-restricted-syntax targeting `x as unknown as Y`, the double-cast pattern used throughout this migration to bypass type checking for protected-member access, constructor-return mismatches, and similar. New occurrences now get flagged everywhere except a fixed list of 12 files with an existing, individually-reviewed need for it. Went through every existing case first to see how many were actually just unenforced coercion rather than a real shape assertion. Nine were: places using the cast purely so a Term/Error/number-or-undefined value could be concatenated or compared, with no branching in between that depends on the pre-coercion value's identity or truthiness (verified each individually — a few similar-looking cases in ExternalHdtDatasource and SparqlDatasource do have an intervening `||` truthiness check on the Term itself, where eager String() coercion would change behavior, so those were left as casts). Replaced with String(x)/Number(x), which carries the same coercion without asserting a lie about the type. The remaining twelve files keep the cast, exempted from the rule at the file level rather than with inline eslint-disable comments (per feedback — too much noise for this many call sites): protected third-party member access confirmed unfixable by declaration merging, constructor-return-type mismatches, and deliberate signature violations that were already reviewed individually across the last few commits. Verified: typecheck, build, lint (0 problems), and all 597 tests pass.
The test job went straight from yarn install to yarn run test-ci, but the compiled .js output has been gitignored throughout this migration (correctly, as build output), so a fresh CI checkout never had it. Node fell back to loading the .ts source directly - recent versions can natively strip plain type annotations, but not `import X = require(...)`, which needs real transformation rather than erasure. That's this codebase's standard import syntax throughout, hence the SyntaxError: Unexpected token '=' on nearly every test file. Reproduced locally by moving out all 168 locally-built compiled files (simulating a from-scratch checkout) and running test-ci - identical stack trace, down to the line and column. Confirmed the fix by adding the build step and rerunning the same sequence: 597/597 passing.
IndexDatasource, WebIDControllerExtension, TimegateController, and MementoControllerExtension have never had tests at any point in this project's ~10-year history (traced back to their original introducing commits) - not a regression from the TS migration, a pre-existing gap. Two of them (IndexDatasource, TimegateController) got real behavior changes during this migration's ! and cast audits, which is the concrete reason to close the gap now rather than defer it further. IndexDatasource: full coverage of the constructor's datasources fallback (confirmed meaningful by reverting the fix and watching the test reproduce the exact crash) and quad generation (visible/hidden/ no-URL/"/"-excluded datasources). TimegateController + MementoControllerExtension: the date-matching algorithm including the gap-between-intervals case, the static map-building methods (including today's String(datasourceId) fix, though that turned out to be a pure honesty improvement with no behavior difference from the cast it replaced), and request handling via both DummyServer/supertest and direct method invocation. WebIDControllerExtension: covers what's actually reachable. The class can't be constructed - lru-cache v5 is a class and the constructor calls it as a plain function, a pre-existing bug preserved as-is - and _verifyWebID crashes the same way on n3's Parser before reaching any of its real logic. Rather than fake coverage, one test documents that construction throws (so it fails loudly if that ever changes), and the two methods that are reachable without hitting either crash (_handleRequest's protocol gate, _handleNotAcceptable's formatting) are tested directly against the prototype. Added the missing test/.eslintrc (mocha globals) to feature-webid and feature-memento, since neither test directory existed before. All plain .js/mocha/chai/sinon, matching every other test in the suite - deferred vitest migration applies here too. Verified: typecheck, build, lint (0 problems), and the full suite (645 passing, up from 597) all clean.
Several files independently re-declared the same settings-cast shape (SummaryController's summaries config, TimegateController's datasource timegate/id fields, IndexDatasource's role) as inline object-literal casts. Extract each into one named type per package/file and reuse it, instead of repeating the literal shape at every call site. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces each remaining as-unknown-as-X cast with an honest
alternative: subclass-style visibility widening for asynciterator's
protected _push, direct narrowing casts where a real subtype
relationship exists (via net.Server as the common ancestor for
http/https servers), a properly dual-signature ErrorType in Util, and
outright bug fixes where the cast was hiding one (Datasource.select
returning a real empty() iterator instead of undefined, CliRunner
using the modern exitedAfterDisconnect instead of the removed
suicide property, QuadPatternFragmentsController seeding query.features
with {} instead of [] to match what every router already assumes).
Trims the no-restricted-syntax exemption list down to the one
remaining case (HdtDatasource's constructor swapping in a sibling
class instance), which needs a real architectural change to resolve.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…y casts
Pushable<T> was defined identically (hardcoded to Quad) in five separate
files; moves it to a single generic export in core's types.ts, imported
everywhere it's used instead of redeclared.
Adds a real overload to n3's Parser#parse for the stream-input case
(verified against N3Lexer's actual source: it branches on typeof input,
duck-typing setEncoding/on('data'|'end'|'error') otherwise), removing the
`as any` casts in ExternalHdtDatasource and N3Datasource that were
bridging around the missing overload. Also replaces the remaining as-any
casts in HdtDatasource (dataFactory param narrowed to hdt.fromFile's own
declared parameter type; the close().then callback pair no longer needs
casting once the fulfilled branch is adapted to hdt's void resolution)
and ExternalHdtDatasource (parseInt's match array replaced with the
actual matched string).
Makes the LinkedDataFragmentsServer http.createServer() branch route
through net.Server the same way the https branch already needs to,
instead of one branch getting a shorter cast than the other for no
documented reason. Also drops three no-op `no-redeclare` eslint-disable
comments left over from the namespace-merge pattern — the rule is
already off for all .ts files.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This mocha/chai test file was added for coverage purposes but belongs on the plain-JS improve-test-coverage branch, not here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
parser.parse(res, ...) now type-checks directly against the N3ParseableInput overload added to types/n3-augment.d.ts, since http.IncomingMessage satisfies it as a real Readable stream. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
15b049e to
3210fae
Compare
|
Fixed, the conflict was because Typescript was branched off master before modernize-repository's CI-modernization commit merged. Rebased Typescript onto modernize-repository's current tip to fix this. tests not converted is correct, that's intentional for this PR (see changed description), they stay JS now and get their own follow-up PR when they are added upon and refactored to Vitest. there is a slight coverage dip, will be handled in the follow-up PR. |
jitsedesmet
left a comment
There was a problem hiding this comment.
These same questions I have repeated themselves quite often throughout this PR. I stopped reviewing in the middle since the same things seem to come back often and are consistent accross packages.
| "packages/*/index.d.ts", | ||
| "packages/*/lib/**/*.d.ts", | ||
| "packages/*/bin/**/*.d.ts" |
There was a problem hiding this comment.
Do we need to explicitly exclude these?
| # Compiled output for packages already converted to TypeScript | ||
| packages/core/lib/**/*.js | ||
| packages/core/lib/**/*.js.map | ||
| packages/core/lib/**/*.d.ts | ||
| packages/core/index.js | ||
| packages/core/index.js.map | ||
| packages/core/index.d.ts |
There was a problem hiding this comment.
There is probably a better way to do this?
|
|
||
| // Read summary triples from file | ||
| let streamParser = new StreamParser({ blankNodePrefix: '', baseIRI: this._baseUrl.pathname }), | ||
| let streamParser = new StreamParser({ blankNodePrefix: '', baseIRI: this._baseUrl.pathname as string }), |
| return next(); | ||
|
|
||
| let summaryMatch = this._matcher && this._matcher.exec(request.url), datasource; | ||
| let summaryMatch = this._matcher && this._matcher.exec(request.url!), datasource; |
| namespace SummaryController { | ||
| export interface SummariesConfig { | ||
| dir?: string; | ||
| path?: string; | ||
| } | ||
| } |
| import * as path from 'path'; | ||
| import { StreamParser } from 'n3'; | ||
| import Util = require('@ldf/core/lib/Util'); | ||
| import type { ControllerOptions, LdfRequest, LdfResponse } from '@ldf/core/lib/types'; |
| /* Exports of the components of this package */ | ||
|
|
||
| module.exports = { | ||
| export = { |
…x lib check errors
Co-authored-by: Jitse De Smet <35114273+jitsedesmet@users.noreply.github.com>
Drop unnecessary any/!/undefined left over from the TS conversion, and switch Util.ts to a namespace + export= so it compiles to a plain module.exports like the rest of the codebase.
public constructors, const over let, and narrow types instead of casting where possible.
This PR starts converting the codebase to TypeScript,
Adds type support for the codebase, converting every package expect the tests (which will be refactored in a different PR) from JavaScript to TypeScript while preserving existing runtime behavior and adding stricter typing throughout.
Part of #206 (item 3: Migrate to TypeScript).