如何在 zod 中创建文件类型“Record<string, File>”的类型

Hel*_*end 8 javascript input-type-file typescript reactjs zod

我使用输入type="file",而不是保存数据,FileData我只使用普通对象并为其创建一个类型:Record<string, File>。它工作得很好,但是当我尝试使用zod\xe2\x80\x93 创建验证器时,我不知道如何为其创建相同的类型。

\n

用法:

\n
import { object as zodObject, string, number } from \'zod\';\nimport { useValidators } from \'../some\';\n\nconst useValidation = () => {\n  const { createResolver } = useValidators();\n  \n  return {\n    resolver: createResolver(\n      zodObject({\n        name: string(),\n        price: number(),\n        files: ???,  \n      })\n    ),\n  };\n}; \n
Run Code Online (Sandbox Code Playgroud)\n

该文档相当过多,但我找不到适合我的案例的任何示例: https: //github.com/colinhacks/zod

\n

输入法的使用:

\n
\nconst App = () => {\n  const [files, setFiles] = useState<Record<string, File>>({}); \n\n  return (\n    <input \n      type="file" \n      onChange={event => {\n        const files = event.target.files;\n        const newFiles: Record<string, File> = {};\n        const keys = Object.keys(files);\n        \n        for(let i = 0; i < keys.length; i++) {\n          const file = newFiles[key];\n          newFiles[file.name] = file;\n        }\n\n        setFiles(newFiles);\n      }}\n    />\n\n  )\n\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

Rin*_*Rin 11

或许z.instanceof可以解决?

如果您想验证文件类型...

z.instanceof (File)

或者,对于 FileList 类型...

z.instanceof (FileList)


https://github.com/colinhacks/zod/issues/387

  • @TomášHübelbauer 正如 [doc](https://zod.dev/?id=custom-schemas) 所建议的, `z.custom&lt;File&gt;()` 将不执行任何验证。我们需要向其传递一个验证函数,代码可能类似于“z.custom&lt;File&gt;((file) =&gt; file instanceof File)” (3认同)

Hel*_*end -2

我的同事找到了解决方案:

// useValidation file
import { object as zodObject, string, number, record, any } from 'zod';
import { useValidators } from '../some';

const useValidation = () => {
  const { createResolver } = useValidators();
  
  return {
    resolver: createResolver(
      zodObject({
        name: string(),
        price: number(),
        files: record(any()).nullable(),  
      })
    ),
  };
};  

Run Code Online (Sandbox Code Playgroud)

在使用带有文件数据的对象的文件中,我们以这种方式使用它:

// fileInput on `onRemove` action return `fileName: string` and my file object looks like this:  { fileName: File } 

const [files, setFiles] = useState<Record<string, File> | null>(null);

<FileInput 
  onChange={(fileName) => {
    const updatedFiles = { ...files as Record<string, File> }; 
    delete updatedFiles[fileName];
    setFiles(updatedFiles);
  }}
/>
Run Code Online (Sandbox Code Playgroud)