From: Ardis Lu Date: Mon, 15 Sep 2025 04:46:17 +0000 (-0700) Subject: Add manual type overrides X-Git-Tag: v0.1.6~5 X-Git-Url: https://git.ardis.lu/?a=commitdiff_plain;h=9688db8948a32e97b4841ede3bcbf600366da07e;p=csvio Add manual type overrides --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4d3b97a..c7968d7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,6 +12,8 @@ npm run types:check All reasonable type issues (i.e., those not resulting from limitations of `tsc`) should be fixed. +To work around `tsc` limitations, add manual type definitions in `./npm/ambient.d.ts`. These type definitions are appended to the output of `tsc` and override the `tsc` outputs if there are conflicts. + ## 2. Tests Run tests: diff --git a/npm/ambient.d.ts b/npm/ambient.d.ts new file mode 100644 index 0000000..5d50ce6 --- /dev/null +++ b/npm/ambient.d.ts @@ -0,0 +1,48 @@ +/** Manual type overrides */ + +// TypeScript does not support setting a return type on a class constructor. +// Workaround: +// - Instead of a class, use a const and inherit an interface (the const and the interface can use the same name for convenience) +// - Declare the constructors as overloaded `new` functions +// - Put static methods in the constant definition +// - Put instance methods in the interface definition +// See https://github.com/microsoft/TypeScript/issues/27594 +// Workaround source: https://github.com/microsoft/TypeScript/issues/27594#issuecomment-566836640 + +import { ReadableStream, WritableStream, TransformStream } from 'node:stream/web'; + +interface CSVReader {} + +/** + * A simple streaming parser for CSV files. + * + * Each chunk is one row of the CSV file as an `Array`. + */ +export declare const CSVReader: { + new(path: PathLike, options?: CSVReaderOptions): CSVReader & ReadableStream>; + new(path?: null): CSVReader & TransformStream>; +} + +interface CSVWriter { + status: CSVWriterStatus; +} + +/** + * Write a streamed CSV file to disk. + * + * A simple wrapper around Node.js's [`fs.writeFile`](https://nodejs.org/api/fs.html#fspromiseswritefilefile-data-options) to write + * streamed data to a file. If the input data is JSON, the data is converted to a string representing a RFC 4180 CSV record. If the + * data is not JSON (e.g., if it is already converted to a CSV string), the data is written to the CSV file directly. + */ +export declare const CSVWriter: { + /** + * Convert a JavaScript array into a CSV string. + * + * @param {Array} arr An array of strings representing one row of a CSV file. + * @returns {string} A string representing one row of a CSV file, with character escaping and line endings compliant with + * [RFC 4180](https://www.ietf.org/rfc/rfc4180.txt). + */ + arrayToCSVString(arr: Array): string; + new(path: PathLike): CSVWriter & WritableStream; + new(path?: null): CSVWriter & TransformStream, string>; +} diff --git a/npm/posttypes.js b/npm/posttypes.js new file mode 100644 index 0000000..d418686 --- /dev/null +++ b/npm/posttypes.js @@ -0,0 +1,7 @@ +import { appendFile, readFile } from 'node:fs/promises'; + +// Inject manually-defined types to work around TypeScript limitations. Note that a re-export +// will not work, the overrides MUST be defined within the top-level index.d.ts to work. +const ambient = await readFile('./npm/ambient.d.ts'); +await appendFile('./types/index.d.ts', '\n\n'); +await appendFile('./types/index.d.ts', ambient); diff --git a/package.json b/package.json index d58c3c2..06a97d1 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ }, "scripts": { "types": "tsc", + "posttypes": "node ./npm/posttypes.js", "types:check": "tsc --noEmit --checkJS", "test": "node --test --test-skip-pattern=\"/^large:/\"", "test:large": "node --test --test-name-pattern=\"/^large:/\" --expose-gc",