TypeScript实现跨对象数组的对象迁移:定义List类型及move函数解决方案
Let's walk through how to build the move function properly, starting with precise type definitions and then handling the core logic plus required error cases.
Step 1: Define Clear Type Interfaces
First, replace the generic List type with specific interfaces that match your data structure—this gives you TypeScript's type safety and autocompletion:
interface File { id: string; name: string; } interface Folder { id: string; name: string; files: File[]; } type List = Folder[];
Step 2: Implement the move Function
The function needs to handle copying the input data (to avoid mutating the original), validating inputs, and performing the file transfer. Here's the full implementation:
interface File { id: string; name: string; } interface Folder { id: string; name: string; files: File[]; } type List = Folder[]; export default function move(list: List, source: string, destination: string): List { // Create a deep copy of the input list to avoid modifying the original data const copiedList = JSON.parse(JSON.stringify(list)) as List; // Locate the source file and its parent folder let sourceFile: File | undefined; let sourceFolder: Folder | undefined; for (const folder of copiedList) { sourceFile = folder.files.find(file => file.id === source); if (sourceFile) { sourceFolder = folder; break; } } // Check if source is a folder (not a file) const isSourceFolder = copiedList.some(folder => folder.id === source); if (isSourceFolder) { throw new Error('You cannot move a folder'); } // Guard clause for missing source file if (!sourceFile || !sourceFolder) { throw new Error('Source file not found'); } // Validate destination is not a file const isDestFile = copiedList.some(folder => folder.files.some(file => file.id === destination)); if (isDestFile) { throw new Error('You cannot specify a file as the destination'); } // Locate the destination folder const destFolder = copiedList.find(folder => folder.id === destination); if (!destFolder) { throw new Error('Destination folder not found'); } // Remove the file from the source folder sourceFolder.files = sourceFolder.files.filter(file => file.id !== source); // Add the file to the destination folder destFolder.files.push(sourceFile); return copiedList; }
Step 3: Key Details Explained
- Deep Copy: Using
JSON.parse(JSON.stringify(list))is a straightforward way to deep copy your plain-object data here. For more complex structures (like dates or functions), you'd use a dedicated deep copy utility, but this works perfectly for your test cases. - Input Validation: We first check if the source is a folder (and throw an error if so), then verify the destination isn't a file. These checks align exactly with your test requirements.
- Mutation Safety: By working on a copied list, we ensure the original input remains unchanged—this follows common functional programming practices and matches how your tests expect the function to behave.
This implementation will pass all your provided test cases: it correctly moves files between folders, throws errors for invalid source/destination types, and handles edge cases like missing files/folders.
内容的提问来源于stack exchange,提问作者Steven Ducker

