首页 > 解决方案 > TypeScript:如何将文件导入 index.ts 而不会获得未定义的数据

问题描述

我目前有这个逻辑:

import { readFileSync } from "fs";

export class Data {
  Address: string;
  General_Plan_Designation: string;
  Latitude: number;
  Longitude: number;

  static DELIMITER = ",";

  constructor(rawRow: string) {
    const data = rawRow.split(Data.DELIMITER);

    this.Address = data[0];
    this.General_Plan_Designation = data[1];
    this.Latitude = parseFloat(data[2]);
    this.Longitude = parseFloat(data[3]);
  }
}

const ROW_DELIMITER = "\r\n";

const rawData = readFileSync("src/Cales_trim_down.csv", {
  encoding: "utf-8",
});

const data: Data[] = [];

for (const rawRow of rawData.split(ROW_DELIMITER)) {
  data.push(new Data(rawRow));
}

哪个成功控制台记录以下内容:

[start:run]   Address {
[start:run]     Address: '138 Stockton Ave',
[start:run]     Latitude: 37.3327991,
[start:run]     Longitude: -121.9040357
[start:run]   },
[start:run]   Address {
[start:run]     Address: '641 N Capitol Av ',
[start:run]     Latitude: 37.3762739,
[start:run]     Longitude: -121.8496285
[start:run]   },
[start:run]   Address {
[start:run]     Address: '535 N 7th St ',
[start:run]     Latitude: 37.348071,
[start:run]     Longitude: -121.8911488
[start:run]   },
[start:run]   Address {
[start:run]     Address: '750 W San Carlos St ',
[start:run]     Latitude: 37.3234717,
[start:run]     Longitude: -121.9044348
[start:run]   },

我将它放在自己的Data.ts文件中,然后将其导入index.ts文件中,但如果我这样做:

import { Data } from "./Data";

const data = new Data('Cales_trim_down.csv');

console.log(data);

我必须传入一些参数,例如 csv 文件作为字符串,然后我得到这个数据结构:

    Data {Address: "Cales_trim_down.csv", General_Plan_Designation: undefined, Latitude: NaN, Longitude: NaN}
     Address: "Cales_trim_down.csv"
     General_Plan_Designation: undefined
     Latitude: NaN
     Longitude: NaN
     __proto__: Object

和我以前的完全不同。Data在不丢失控制台记录的数据完整性的情况下,将该类导入回我的项目的根文件的最佳方法是什么?

如果我不必将 传递Cales_trim_down.csv给 的实例,那将是理想的Data,但我无法以Data不必将任何参数传递给构造函数的方式重构类。提前声明filename并不能解决问题。

我的另一个想法是我不应该传递 but 的字符串cales_trim_down.csvrawData但是当我这样做时,它告诉我它找不到rawData

标签: javascriptnode.jstypescript

解决方案


在第一个实例中,您将单行数据提供给循环Data内的构造函数。for数据是在使用中加载的readFileSync("src/Cales_trim_down.csv")。在第二种情况下,您正在输入new Data一个字符串,它是文件的位置。这是两个完全不同的论点。在第二种情况下,您的Data实例实际上并没有读入任何数据,这就是所有值都未定义的原因。这与您将类模块化这一事实无关Data,而与您用于创建new Data实例的内容无关。

在自己的文件中定义您的 Data 类:

// Data.ts
export class Data {
  // ... all the same logic as before
}

然后使用与之前相同的逻辑:

import { Data } from "./Data";

// const data = new Data('Cales_trim_down.csv'); <--- No!

const ROW_DELIMITER = "\r\n";

const rawData = readFileSync("src/Cales_trim_down.csv", {
  encoding: "utf-8",
});

const data: Data[] = [];

for (const rawRow of rawData.split(ROW_DELIMITER)) {
  data.push(new Data(rawRow));
}

编辑:保持在课堂上

另一种可能更简洁的选择是将所有这些与数据相关的方法保留在数据类本身中:

// Data.ts
import { readFileSync } from "fs";

export class Data {
  rawData: string;
  data: {
    Address: string;
    General_Plan_Designation: string;
    Latitude: number;
    Longitude: number;
  }[];

  static DELIMITER = ",";
  static ROW_DELIMITER = "\n";

  constructor(filepath: string) {
    this.rawData = readFileSync(filepath, {
      encoding: "utf-8"
    });
    this.data = [];
    this.processData();
  }

  processData() {
    for (const rawRow of this.rawData.split(Data.ROW_DELIMITER)) {
      this.processRow(rawRow);
    }
  }

  processRow(rowstring: string) {
    const rowarray = rowstring.split(Data.DELIMITER);
    const formattedRow = {
      Address: rowarray[0],
      General_Plan_Designation: rowarray[1],
      Latitude: Number(rowarray[2]),
      Longitude: Number(rowarray[3])
    };
    this.data.push(formattedRow);
  }
}

// SomewherElse.ts

const filepath = path.resolve(__dirname, "sampledata.txt");
const myData = new Data(filepath);
console.log(myData.data);

工作节点 TS 沙箱

所以现在所有的数据方法,包括读入数据、解析行等,都包含Data类中。我认为这会更整洁。

此外,您似乎正在尝试使用此代码将 CSV 转换为 JSON?当然肯定有一些图书馆已经这样做了?


推荐阅读