【发布时间】:2021-11-05 16:02:52
【问题描述】:
我有以下 json 架构要使用 Typescript 处理(具有 100 MB 条目的文件)。
[
{
"firstName":"Emma",
"lastName":"Sall",
"country":"US",
"email":"test@hotmail.com",
"dob":"1944-05-05T13:14:32.526Z",
"mfa":"SMS",
"amt":962169704,
"createdDate":"2020-08-15T20:07:24.157Z",
"referredBy":null
},
{
"firstName":"Darren",
"lastName":"test",
"country":"ES",
"email":"test334@yahoo.com",
"dob":"1944-02-11T19:44:58.715Z",
"mfa":"SMS",
"amt":239723064,
"createdDate":"2020-07-12T12:39:47.553Z",
"referredBy":null
},
...
...
...
]
在这两行对数组进行排序时出现此错误(下面的完整代码):
a[accountSearchCriteria.sortField] <
b[accountSearchCriteria.sortField]
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Account'. No index signature with a parameter of type 'string' was found on type 'Account'.
我正在使用以下代码来处理文件main.ts:
import fs from 'fs';
const accountSearchCriteria: AccountSearchCriteria = {
country: 'CA',
mfa: 'SMS',
name: 'TEST',
sortField: 'amt'
};
const jsonPath = './test/src.json';
const rawAccounts = fs.readFileSync(jsonPath, 'utf-8');
let accounts: Account[] = JSON.parse(rawAccounts);
if (accountSearchCriteria) {
if (accountSearchCriteria.name) {
accounts = accounts.filter(
account =>
account.firstName.toLowerCase() ===
accountSearchCriteria.name.toLowerCase() ||
account.lastName.toLowerCase() ===
accountSearchCriteria.name.toLowerCase()
);
}
if (accountSearchCriteria.country) {
accounts = accounts.filter(
account =>
account.country.toLowerCase() ===
accountSearchCriteria.country.toLowerCase()
);
}
if (accountSearchCriteria.mfa) {
accounts = accounts.filter(
account => account.mfa === accountSearchCriteria.mfa
);
}
if (accountSearchCriteria.sortField) {
accounts.sort((a, b) =>
a[accountSearchCriteria.sortField] <
b[accountSearchCriteria.sortField]
? -1
: 1
);
}
return accounts;
}
return accounts;
接口定义如下account.ts:
export interface Account {
firstName: string;
lastName: string;
country: string;
email: string;
dob: string;
mfa?: MFA;
amt: number;
createdDate: string;
referredBy?: string;
}
export enum MFA {
SMS = 'SMS',
TOTP = 'TOTP'
}
export interface AccountSearchCriteria {
country?: string;
mfa?: string;
name?: string;
sortField?: string;
}
此外,代码需要很长时间来处理我想要读取的文件,它是 100 MB,我针对一个小文件对其进行了测试,它运行良好。有没有更快的方法来改进代码并提高效率?
【问题讨论】:
-
sortField的类型是string | undefined,但在您进行a[...] < b[...]比较时缩小到仅string。 TS 抱怨的原因是a不是一个可以将任意字符串作为键的对象。不允许使用a[arbitraryString]。为了使它起作用,您有 3 个选项。 1) 使用index signature 使a通常可索引 2) 使用theRecordtype 使a通常可索引 -
3) 将
sortField的类型更改为keyof Account或以其他方式确保sortField仅作为Account接口的有效键输入。这可能是你最好的选择,因为在你的Account接口中允许任意字符串并不是最好的主意(即使它在技术上可能有效) -
@nullromo 非常感谢 cmets,你能给我一个选项号的例子吗? 3个好吗?
-
是的,我会尽快发布答案。
-
@nullromo 非常感谢 .. 另外,不确定是否有办法改进它以读取更大的文件 .. 因为处理它们需要很长时间
标签: javascript node.js json typescript