输入 Object.fromEntries(new FormData(form))

Typing Object.fromEntries(new FormData(form))

这里是 TypeScript 新手,Object.fromEntries 有问题。我正在尝试削减形式并将其价值投射到其他东西上。例如,给定所有数据都是字符串的同质形状,下面的工作:


// example form content:
// {
//    foo: 'bar',
//    bar: 'biz'
//  }
//  return values
// {
//    foo: 'bar',
//    bar: 'biz'
//  }

export const getFormData = (form: HTMLFormElement) => {
  return Object.fromEntries<string>(
    new FormData(form) as Iterable<[PropertyKey, string]>,
  )
}

如何将上面返回的值转换为字符串以外的值?例如:


// example form content:
// {
//    foo: '1',
//    bar: 'biz',
//    biz: 'false'
//  }
//  desired return values
// {
//    foo: 1,
//    bar: 'biz',
//    biz: false
//  }

export const getFormData = (form: HTMLFormElement) => {
  return Object.fromEntries<string>(
    new FormData(form) as Iterable<[PropertyKey, string]>,
  )
}

我的感觉是我可以以某种方式 用泛型和接口修复它,但我不知道如何继续。谁能ELI5 不胜感激

编辑:我的 tsconfig.json

{
    "compilerOptions": {
        "moduleResolution": "node",
        "module": "es2020",
        "lib": ["esnext", "dom", "dom.iterable"],
        "target": "es2020",
        "downlevelIteration": true,
        "importsNotUsedAsValues": "error",
        "preserveValueImports": true,
        "isolatedModules": true,
        "resolveJsonModule": true,
        "sourceMap": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "baseUrl": ".",
        "allowJs": true,
        "checkJs": true,
    }
}

EDIT2:更好地解释期望的结果。

在您的 TS 配置中将“dom.iterable”添加到 lib:

"lib": [
  "es2019",
  "dom",
  "dom.iterable"
],

现在 TS 知道 DOM 元素可以 return 一个 .entries() 迭代器,你不需要再显式输入它了:

Object.fromEntries(new FormData(form))

由于您使用的是 HTML 表单,因此您只会得到字符串和 blob。如果您想将某些字符串转换为数字,转换对您没有帮助。只需迭代条目,并转换符合特定条件的值 - 例如某个键,或者如果将它们转换为数字不会产生 NaN。例如 (TS Playground):

const formData = new FormData();

formData.append('name', 'max');
formData.append('age', '123456');

const result = Object.fromEntries([...formData].map(([key, value]) => [
  key,
  key === 'age' ? +value : value
]))

console.log(result)

如果您不想在 tsconfig.json 中设置 dom.iterable,您可以这样做:

const handleFormSubmit = (evt: SubmitEvent) => {
  const form = evt.target as HTMLFormElement;
  const formData = new FormData(form) as unknown as Iterable<
    [RequestData, FormDataEntryValue]
  >;
  const requestData: RequestData = Object.fromEntries(formData);
  console.log(requestData);
};

其中 RequestData 是这样的接口:

interface RequestData {
  foo: string;
  bar: string;
  biz: string;
}

然后您将完成 requestData 标识符。而且编译器不会大喊大叫。