diff --git a/types/d3-dsv/d3-dsv-tests.ts b/types/d3-dsv/d3-dsv-tests.ts index 51127b7266..459fa7291b 100644 --- a/types/d3-dsv/d3-dsv-tests.ts +++ b/types/d3-dsv/d3-dsv-tests.ts @@ -21,7 +21,7 @@ const tsvTestStringWithHeader = 'Year\tMake\tModel\tLength\n1997\tFord\tE350\t2. const pipedTestStringWithHeader = 'Year|Make|Model|Length\n1997|Ford|E350|2.34\n2000|Mercury|Cougar|2.38'; interface ParsedTestObject { - year: Date; + year: Date | null; make: string; model: string; length: number; @@ -35,8 +35,9 @@ let parseRowsMappedArray: ParsedTestObject[]; let columns: string[]; let num: number; -let date: Date; +let dateNull: Date | null; let str: string; +let strMaybe: string | undefined; // ------------------------------------------------------------------------------------------ // Test CSV @@ -50,7 +51,7 @@ parseArray = d3Dsv.csvParse(csvTestStringWithHeader); columns = parseArray.columns; -str = parseArray[0]['Year']; +strMaybe = parseArray[0]['Year']; // date = parseArray[0]['Year']; // fails, return value is string // with row mapper --------------------------------------------------------------------------- @@ -60,19 +61,39 @@ parseMappedArray = d3Dsv.csvParse(csvTestStringWithHeader, (rawRow, index, colum const i: number = index; const c: string[] = columns; const pr: ParsedTestObject = { - year: new Date(+rr['Year'], 0, 1), - make: rr['Make'], - model: rr['Model'], - length: +rr['Length'] + year: rr['Year'] ? new Date(+rr['Year']!, 0, 1) : null, + make: rr['Make'] ? rr['Make']! : "Missing Value", + model: rr['Model'] ? rr['Model']! : "Missing Value", + length: ['Length'] ? +rr['Length']! : NaN }; return pr; }); +parseMappedArray = d3Dsv.csvParse(csvTestStringWithHeader, (rawRow, index, columns) => { + const rr: d3Dsv.DSVRowString = rawRow; + const i: number = index; + const c: string[] = columns; + const d: number | null = rr['Year'] ? +rr['Year']! : null; + const pr: ParsedTestObject | null | undefined = d !== null + ? ( + d > 1997 + ? { + year: new Date(d, 0, 1), + make: rr['Make'] ? rr['Make']! : "Missing Value", + model: rr['Model'] ? rr['Model']! : "Missing Value", + length: ['Length'] ? +rr['Length']! : NaN + } + : undefined + ) + : null; + return pr; +}); + columns = parseMappedArray.columns; -date = parseMappedArray[0].year; -str = parseMappedArray[0].make; -str = parseMappedArray[0].model; +dateNull = parseMappedArray[0].year; +strMaybe = parseMappedArray[0].make; +strMaybe = parseMappedArray[0].model; num = parseMappedArray[0].length; // csvParseRows(...) ============================================================================ @@ -81,7 +102,7 @@ num = parseMappedArray[0].length; parseRowsArray = d3Dsv.csvParseRows(csvTestString); -str = parseRowsArray[0][0]; // 'Year' of first row +strMaybe = parseRowsArray[0][0]; // 'Year' of first row // date = parseRowsArray[0][0]; // fails, return value is string // with row mapper --------------------------------------------------------------------------- @@ -89,18 +110,25 @@ str = parseRowsArray[0][0]; // 'Year' of first row parseRowsMappedArray = d3Dsv.csvParseRows(csvTestString, (rawRow, index) => { const rr: string[] = rawRow; const i: number = index; - const pr: ParsedTestObject = { - year: new Date(+rr[0], 0, 1), - make: rr[1], - model: rr[2], - length: +rr[3] - }; + const d: number | null = rr[0].length ? +rr[0] : null; + const pr: ParsedTestObject | null | undefined = d !== null + ? ( + d > 1997 + ? { + year: new Date(d, 0, 1), + make: rr[1].length ? rr[1] : "Missing Value", + model: rr[2].length ? rr[2] : "Missing Value", + length: rr[3].length ? +rr[3] : NaN + } + : undefined + ) + : null; return pr; }); -date = parseRowsMappedArray[0].year; -str = parseRowsMappedArray[0].make; -str = parseRowsMappedArray[0].model; +dateNull = parseRowsMappedArray[0].year; +strMaybe = parseRowsMappedArray[0].make; +strMaybe = parseRowsMappedArray[0].model; num = parseRowsMappedArray[0].length; // csvFormat(...) ============================================================================ @@ -111,7 +139,7 @@ str = d3Dsv.csvFormat(parseRowsMappedArray, columns); // csvFormatRows(...) ======================================================================== str = d3Dsv.csvFormatRows(parseRowsMappedArray.map((d, i) => [ - d.year.getFullYear().toString(), + d.year ? d.year.getFullYear().toString() : '', d.make, d.model, d.length.toString() @@ -129,7 +157,7 @@ parseArray = d3Dsv.tsvParse(tsvTestStringWithHeader); columns = parseArray.columns; -str = parseArray[0]['Year']; +strMaybe = parseArray[0]['Year']; // date = parseArray[0]['Year']; // fails, return value is string // with row mapper --------------------------------------------------------------------------- @@ -138,20 +166,27 @@ parseMappedArray = d3Dsv.tsvParse(tsvTestStringWithHeader, (rawRow, index, colum const rr: d3Dsv.DSVRowString = rawRow; const i: number = index; const c: string[] = columns; - const pr: ParsedTestObject = { - year: new Date(+rr['Year'], 0, 1), - make: rr['Make'], - model: rr['Model'], - length: +rr['Length'] - }; + const d: number | null = rr['Year'] ? +rr['Year']! : null; + const pr: ParsedTestObject | null | undefined = d !== null + ? ( + d > 1997 + ? { + year: new Date(d, 0, 1), + make: rr['Make'] ? rr['Make']! : "Missing Value", + model: rr['Model'] ? rr['Model']! : "Missing Value", + length: ['Length'] ? +rr['Length']! : NaN + } + : undefined + ) + : null; return pr; }); columns = parseMappedArray.columns; -date = parseMappedArray[0].year; -str = parseMappedArray[0].make; -str = parseMappedArray[0].model; +dateNull = parseMappedArray[0].year; +strMaybe = parseMappedArray[0].make; +strMaybe = parseMappedArray[0].model; num = parseMappedArray[0].length; // tsvParseRows(...) ============================================================================ @@ -160,7 +195,7 @@ num = parseMappedArray[0].length; parseRowsArray = d3Dsv.tsvParseRows(tsvTestString); -str = parseRowsArray[0][0]; // 'Year' of first row +strMaybe = parseRowsArray[0][0]; // 'Year' of first row // date = parseRowsArray[0][0]; // fails, return value is string // with row mapper --------------------------------------------------------------------------- @@ -168,18 +203,25 @@ str = parseRowsArray[0][0]; // 'Year' of first row parseRowsMappedArray = d3Dsv.tsvParseRows(tsvTestString, (rawRow, index) => { const rr: string[] = rawRow; const i: number = index; - const pr: ParsedTestObject = { - year: new Date(+rr[0], 0, 1), - make: rr[1], - model: rr[2], - length: +rr[3] - }; + const d: number | null = rr[0].length ? +rr[0] : null; + const pr: ParsedTestObject | null | undefined = d !== null + ? ( + d > 1997 + ? { + year: new Date(d, 0, 1), + make: rr[1].length ? rr[1] : "Missing Value", + model: rr[2].length ? rr[2] : "Missing Value", + length: rr[3].length ? +rr[3] : NaN + } + : undefined + ) + : null; return pr; }); -date = parseRowsMappedArray[0].year; -str = parseRowsMappedArray[0].make; -str = parseRowsMappedArray[0].model; +dateNull = parseRowsMappedArray[0].year; +strMaybe = parseRowsMappedArray[0].make; +strMaybe = parseRowsMappedArray[0].model; num = parseRowsMappedArray[0].length; // tsvFormat(...) ============================================================================ @@ -190,7 +232,7 @@ str = d3Dsv.tsvFormat(parseRowsMappedArray, columns); // tsvFormatRows(...) ======================================================================== str = d3Dsv.tsvFormatRows(parseRowsMappedArray.map((d, i) => [ - d.year.getFullYear().toString(), + d.year ? d.year.getFullYear().toString() : '', d.make, d.model, d.length.toString() @@ -213,7 +255,7 @@ parseArray = dsv.parse(pipedTestStringWithHeader); columns = parseArray.columns; -str = parseArray[0]['Year']; +strMaybe = parseArray[0]['Year']; // date = parseArray[0]['Year']; // fails, return value is string // with row mapper --------------------------------------------------------------------------- @@ -222,20 +264,27 @@ parseMappedArray = dsv.parse(pipedTestStringWithHeader, (rawRow, index, columns) const rr: d3Dsv.DSVRowString = rawRow; const i: number = index; const c: string[] = columns; - const pr: ParsedTestObject = { - year: new Date(+rr['Year'], 0, 1), - make: rr['Make'], - model: rr['Model'], - length: +rr['Length'] - }; + const d: number | null = rr['Year'] ? +rr['Year']! : null; + const pr: ParsedTestObject | null | undefined = d !== null + ? ( + d > 1997 + ? { + year: new Date(d, 0, 1), + make: rr['Make'] ? rr['Make']! : "Missing Value", + model: rr['Model'] ? rr['Model']! : "Missing Value", + length: ['Length'] ? +rr['Length']! : NaN + } + : undefined + ) + : null; return pr; }); columns = parseMappedArray.columns; -date = parseMappedArray[0].year; -str = parseMappedArray[0].make; -str = parseMappedArray[0].model; +dateNull = parseMappedArray[0].year; +strMaybe = parseMappedArray[0].make; +strMaybe = parseMappedArray[0].model; num = parseMappedArray[0].length; // parseRows(...) ============================================================================ @@ -244,7 +293,7 @@ num = parseMappedArray[0].length; parseRowsArray = dsv.parseRows(pipedTestString); -str = parseRowsArray[0][0]; // 'Year' of first row +strMaybe = parseRowsArray[0][0]; // 'Year' of first row // date = parseRowsArray[0][0]; // fails, return value is string // with row mapper --------------------------------------------------------------------------- @@ -252,18 +301,25 @@ str = parseRowsArray[0][0]; // 'Year' of first row parseRowsMappedArray = dsv.parseRows(pipedTestString, (rawRow, index) => { const rr: string[] = rawRow; const i: number = index; - const pr: ParsedTestObject = { - year: new Date(+rr[0], 0, 1), - make: rr[1], - model: rr[2], - length: +rr[3] - }; + const d: number | null = rr[0].length ? +rr[0] : null; + const pr: ParsedTestObject | null | undefined = d !== null + ? ( + d > 1997 + ? { + year: new Date(d, 0, 1), + make: rr[1].length ? rr[1] : "Missing Value", + model: rr[2].length ? rr[2] : "Missing Value", + length: rr[3].length ? +rr[3] : NaN + } + : undefined + ) + : null; return pr; }); -date = parseRowsMappedArray[0].year; -str = parseRowsMappedArray[0].make; -str = parseRowsMappedArray[0].model; +dateNull = parseRowsMappedArray[0].year; +strMaybe = parseRowsMappedArray[0].make; +strMaybe = parseRowsMappedArray[0].model; num = parseRowsMappedArray[0].length; // format(...) ============================================================================ @@ -274,7 +330,7 @@ str = dsv.format(parseRowsMappedArray, columns); // formatRows(...) ======================================================================== str = dsv.formatRows(parseRowsMappedArray.map((d, i) => [ - d.year.getFullYear().toString(), + d.year ? d.year.getFullYear().toString() : '', d.make, d.model, d.length.toString() diff --git a/types/d3-dsv/index.d.ts b/types/d3-dsv/index.d.ts index eaf9797b02..80b2ebc54e 100644 --- a/types/d3-dsv/index.d.ts +++ b/types/d3-dsv/index.d.ts @@ -3,19 +3,35 @@ // Definitions by: Tom Wanzek , Alex Ford , Boris Yankov // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// Last module patch version validated against: 1.0.30 + // ------------------------------------------------------------------------------------------ // Shared Types and Interfaces // ------------------------------------------------------------------------------------------ +/** + * An object representing a DSV parsed row with values represented as strings. + */ export interface DSVRowString { - [key: string]: string; + [key: string]: string | undefined; } +/** + * An object representing a DSV parsed row with values represented as an arbitrary datatype, depending + * on the performed parsed row mapping. + */ export interface DSVRowAny { [key: string]: any; } +/** + * An array object representing all parsed rows. The array is enhanced with a property listing + * the names of the parsed columns. + */ export interface DSVParsedArray extends Array { + /** + * List of column names. + */ columns: string[]; } @@ -25,20 +41,108 @@ export interface DSVParsedArray extends Array { // csvParse(...) ============================================================================ +/** + * Parses the specified string, which must be in the comma-separated values format, returning an array of objects representing the parsed rows. + * + * Unlike csvParseRows, this method requires that the first line of the CSV content contains a comma-separated list of column names; + * these column names become the attributes on the returned objects. + * + * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). + * + * Equivalent to dsvFormat(",").parse. + * + * @param csvString A string, which must be in the comma-separated values format. + */ export function csvParse(csvString: string): DSVParsedArray; -export function csvParse(csvString: string, row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow): DSVParsedArray; +/** + * Parses the specified string, which must be in the comma-separated values format, returning an array of objects representing the parsed rows. + * + * Unlike csvParseRows, this method requires that the first line of the CSV content contains a comma-separated list of column names; + * these column names become the attributes on the returned objects. + * + * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). + * + * Equivalent to dsvFormat(",").parse. + * + * @param csvString A string, which must be in the comma-separated values format. + * @param row A row conversion function which is invoked for each row, being passed an object representing the current row (d), + * the index (i) starting at zero for the first non-header row, and the array of column names. If the returned value is null or undefined, + * the row is skipped and will be ommitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. + * In effect, row is similar to applying a map and filter operator to the returned rows. + */ +export function csvParse( + csvString: string, + row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null +): DSVParsedArray; // csvParseRows(...) ======================================================================== +/** + * Parses the specified string, which must be in the comma-separated values format, returning an array of arrays representing the parsed rows. + * + * Unlike csvParse, this method treats the header line as a standard row, and should be used whenever CSV content does not contain a header. + * Each row is represented as an array rather than an object. Rows may have variable length. + * + * If a row conversion function is not specified, field values are strings. For safety, there is no automatic conversion to numbers, dates, or other types. + * In some cases, JavaScript may coerce strings to numbers for you automatically (for example, using the + operator), but better is to specify a row conversion function. + * + * Equivalent to dsvFormat(",").parseRows. + * + * @param csvString A string, which must be in the comma-separated values format. + */ export function csvParseRows(csvString: string): string[][]; -export function csvParseRows(csvString: string, row: (rawRow: string[], index: number) => ParsedRow): ParsedRow[]; +/** + * Parses the specified string, which must be in the comma-separated values format, returning an array of arrays representing the parsed rows. + * + * Unlike csvParse, this method treats the header line as a standard row, and should be used whenever CSV content does not contain a header. + * Each row is represented as an array rather than an object. Rows may have variable length. + * + * Equivalent to dsvFormat(",").parseRows. + * + * @param csvString A string, which must be in the comma-separated values format. + * @param row A row conversion function which is invoked for each row, being passed an array representing the current row (d), the index (i) + * starting at zero for the first row, and the array of column names. If the returned value is null or undefined, + * the row is skipped and will be ommitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. + * In effect, row is similar to applying a map and filter operator to the returned rows. + */ +export function csvParseRows( + csvString: string, + row: (rawRow: string[], index: number) => ParsedRow | undefined | null +): ParsedRow[]; // csvFormat(...) ============================================================================ +/** + * Formats the specified array of object rows as comma-separated values, returning a string. + * This operation is the inverse of csvParse. Each row will be separated by a newline (\n), + * and each column within each row will be separated by the comma-delimiter. + * Values that contain either the comma-delimiter, a double-quote (") or a newline will be escaped using double-quotes. + * + * If columns is not specified, the list of column names that forms the header row is determined by the union of all properties on all objects in rows; + * the order of columns is nondeterministic. + * + * Equivalent to dsvFormat(",").format. + * + * @param rows Array of object rows. + * @param columns An array of strings representing the column names. + */ export function csvFormat(rows: DSVRowAny[], columns?: string[]): string; // csvFormatRows(...) ======================================================================== +/** + * Formats the specified array of array of string rows as comma-separated values, returning a string. + * This operation is the reverse of csvParseRows. Each row will be separated by a newline (\n), + * and each column within each row will be separated by the comma-delimiter. + * Values that contain either the comma-delimiter, a double-quote (") or a newline will be escaped using double-quotes. + * + * To convert an array of objects to an array of arrays while explicitly specifying the columns, use array.map. + * If you like, you can also array.concat this result with an array of column names to generate the first row. + * + * Equivalent to dsvFormat(",").formatRows. + * + * @param rows An array of array of string rows. + */ export function csvFormatRows(rows: string[][]): string; // ------------------------------------------------------------------------------------------ @@ -47,33 +151,209 @@ export function csvFormatRows(rows: string[][]): string; // tsvParse(...) ============================================================================ +/** + * Parses the specified string, which must be in the tab-separated values format, returning an array of objects representing the parsed rows. + * + * Unlike tsvParseRows, this method requires that the first line of the TSV content contains a tab-separated list of column names; + * these column names become the attributes on the returned objects. + * + * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). + * + * Equivalent to dsvFormat("\t").parse. + * + * @param tsvString A string, which must be in the tab-separated values format. + */ export function tsvParse(tsvString: string): DSVParsedArray; -export function tsvParse(tsvString: string, row: (rawRow: DSVRowString, index: number, columns: string[]) => MappedRow): DSVParsedArray; +/** + * Parses the specified string, which must be in the tab-separated values format, returning an array of objects representing the parsed rows. + * + * Unlike tsvParseRows, this method requires that the first line of the TSV content contains a tab-separated list of column names; + * these column names become the attributes on the returned objects. + * + * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). + * + * Equivalent to dsvFormat("\t").parse. + * + * @param tsvString A string, which must be in the tab-separated values format. + * @param row A row conversion function which is invoked for each row, being passed an object representing the current row (d), + * the index (i) starting at zero for the first non-header row, and the array of column names. If the returned value is null or undefined, + * the row is skipped and will be ommitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. + * In effect, row is similar to applying a map and filter operator to the returned rows. + */ +export function tsvParse( + tsvString: string, + row: (rawRow: DSVRowString, index: number, columns: string[]) => MappedRow | undefined | null +): DSVParsedArray; // tsvParseRows(...) ======================================================================== +/** + * Parses the specified string, which must be in the tab-separated values format, returning an array of arrays representing the parsed rows. + * + * Unlike tsvParse, this method treats the header line as a standard row, and should be used whenever TSV content does not contain a header. + * Each row is represented as an array rather than an object. Rows may have variable length. + * + * If a row conversion function is not specified, field values are strings. For safety, there is no automatic conversion to numbers, dates, or other types. + * In some cases, JavaScript may coerce strings to numbers for you automatically (for example, using the + operator), but better is to specify a row conversion function. + * + * Equivalent to dsvFormat("\t").parseRows. + * + * @param tsvString A string, which must be in the tab-separated values format. + */ export function tsvParseRows(tsvString: string): string[][]; -export function tsvParseRows(tsvString: string, row: (rawRow: string[], index: number) => MappedRow): MappedRow[]; +/** + * Parses the specified string, which must be in the tab-separated values format, returning an array of arrays representing the parsed rows. + * + * Unlike tsvParse, this method treats the header line as a standard row, and should be used whenever TSV content does not contain a header. + * Each row is represented as an array rather than an object. Rows may have variable length. + * + * Equivalent to dsvFormat("\t").parseRows. + * + * @param tsvString A string, which must be in the tab-separated values format. + * @param row A row conversion function which is invoked for each row, being passed an array representing the current row (d), the index (i) + * starting at zero for the first row, and the array of column names. If the returned value is null or undefined, + * the row is skipped and will be ommitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. + * In effect, row is similar to applying a map and filter operator to the returned rows. + */ +export function tsvParseRows( + tsvString: string, + row: (rawRow: string[], index: number) => MappedRow | undefined | null +): MappedRow[]; // tsvFormat(...) ============================================================================ +/** + * Formats the specified array of object rows as tab-separated values, returning a string. + * This operation is the inverse of tsvParse. Each row will be separated by a newline (\n), + * and each column within each row will be separated by the tab-delimiter. + * Values that contain either the tab-delimiter, a double-quote (") or a newline will be escaped using double-quotes. + * + * If columns is not specified, the list of column names that forms the header row is determined by the union of all properties on all objects in rows; + * the order of columns is nondeterministic. + * + * Equivalent to dsvFormat("\t").format. + * + * @param rows Array of object rows. + * @param columns An array of strings representing the column names. + */ export function tsvFormat(rows: DSVRowAny[], columns?: string[]): string; // tsvFormatRows(...) ======================================================================== +/** + * Formats the specified array of array of string rows as tab-separated values, returning a string. + * This operation is the reverse of tsvParseRows. Each row will be separated by a newline (\n), + * and each column within each row will be separated by the tab-delimiter. + * Values that contain either the tab-delimiter, a double-quote (") or a newline will be escaped using double-quotes. + * + * To convert an array of objects to an array of arrays while explicitly specifying the columns, use array.map. + * If you like, you can also array.concat this result with an array of column names to generate the first row. + * + * Equivalent to dsvFormat("\t").formatRows. + * + * @param rows An array of array of string rows. + */ export function tsvFormatRows(rows: string[][]): string; // ------------------------------------------------------------------------------------------ // DSV Generalized Parsers and Formatters // ------------------------------------------------------------------------------------------ +/** + * A DSV parser and formatter + */ export interface DSV { + /** + * Parses the specified string, which must be in the delimiter-separated values format with the appropriate delimiter, returning an array of objects representing the parsed rows. + * + * Unlike dsv.parseRows, this method requires that the first line of the DSV content contains a delimiter-separated list of column names; + * these column names become the attributes on the returned objects. + * + * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). + * + * @param dsvString A string, which must be in the delimiter-separated values format with the appropriate delimiter. + */ parse(dsvString: string): DSVParsedArray; - parse(dsvString: string, row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow): DSVParsedArray; + /** + * Parses the specified string, which must be in the delimiter-separated values format with the appropriate delimiter, returning an array of objects representing the parsed rows. + * + * Unlike dsv.parseRows, this method requires that the first line of the DSV content contains a delimiter-separated list of column names; + * these column names become the attributes on the returned objects. + * + * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). + * + * @param dsvString A string, which must be in the delimiter-separated values format with the appropriate delimiter. + * @param row A row conversion function which is invoked for each row, being passed an object representing the current row (d), + * the index (i) starting at zero for the first non-header row, and the array of column names. If the returned value is null or undefined, + * the row is skipped and will be ommitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. + * In effect, row is similar to applying a map and filter operator to the returned rows. + */ + parse( + dsvString: string, + row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + ): DSVParsedArray; + + /** + * Parses the specified string, which must be in the delimiter-separated values format with the appropriate delimiter, returning an array of arrays representing the parsed rows. + * + * Unlike dsv.parse, this method treats the header line as a standard row, and should be used whenever DSV content does not contain a header. + * Each row is represented as an array rather than an object. Rows may have variable length. + * + * If a row conversion function is not specified, field values are strings. For safety, there is no automatic conversion to numbers, dates, or other types. + * In some cases, JavaScript may coerce strings to numbers for you automatically (for example, using the + operator), but better is to specify a row conversion function. + * + * @param dsvString A string, which must be in the delimiter-separated values format with the appropriate delimiter. + */ parseRows(dsvString: string): string[][]; - parseRows(dsvString: string, row: (rawRow: string[], index: number) => ParsedRow): ParsedRow[]; + /** + * Parses the specified string, which must be in the delimiter-separated values format with the appropriate delimiter, returning an array of arrays representing the parsed rows. + * + * Unlike dsv.parse, this method treats the header line as a standard row, and should be used whenever DSV content does not contain a header. + * Each row is represented as an array rather than an object. Rows may have variable length. + * + * @param dsvString A string, which must be in the delimiter-separated values format with the appropriate delimiter. + * @param row A row conversion function which is invoked for each row, being passed an array representing the current row (d), the index (i) + * starting at zero for the first row, and the array of column names. If the returned value is null or undefined, + * the row is skipped and will be ommitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. + * In effect, row is similar to applying a map and filter operator to the returned rows. + */ + parseRows( + dsvString: string, + row: (rawRow: string[], index: number) => ParsedRow | undefined | null + ): ParsedRow[]; + + /** + * Formats the specified array of object rows as delimiter-separated values, returning a string. + * This operation is the inverse of dsv.parse. Each row will be separated by a newline (\n), + * and each column within each row will be separated by the delimiter (such as a comma, ,). + * Values that contain either the delimiter, a double-quote (") or a newline will be escaped using double-quotes. + * + * If columns is not specified, the list of column names that forms the header row is determined by the union of all properties on all objects in rows; + * the order of columns is nondeterministic. + * + * @param rows Array of object rows. + * @param columns An array of strings representing the column names. + */ format(rows: DSVRowAny[], columns?: string[]): string; + + /** + * Formats the specified array of array of string rows as delimiter-separated values, returning a string. + * This operation is the reverse of dsv.parseRows. Each row will be separated by a newline (\n), + * and each column within each row will be separated by the delimiter (such as a comma, ,). + * Values that contain either the delimiter, a double-quote (") or a newline will be escaped using double-quotes. + * + * To convert an array of objects to an array of arrays while explicitly specifying the columns, use array.map. + * If you like, you can also array.concat this result with an array of column names to generate the first row. + * + * @param rows An array of array of string rows. + */ formatRows(rows: string[][]): string; } +/** + * Constructs a new DSV parser and formatter for the specified delimiter. + * + * @param delimiter A delimiter character. The delimiter must be a single character (i.e., a single 16-bit code unit); + * so, ASCII delimiters are fine, but emoji delimiters are not. + */ export function dsvFormat(delimiter: string): DSV; diff --git a/types/d3-dsv/tsconfig.json b/types/d3-dsv/tsconfig.json index 82e3ef399f..400095c38d 100644 --- a/types/d3-dsv/tsconfig.json +++ b/types/d3-dsv/tsconfig.json @@ -6,7 +6,7 @@ ], "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": false, + "strictNullChecks": true, "strictFunctionTypes": true, "baseUrl": "../", "typeRoots": [ @@ -20,4 +20,4 @@ "index.d.ts", "d3-dsv-tests.ts" ] -} \ No newline at end of file +}