TypeScript中转换Reduce方法后逻辑异常,请求技术协助
Fixing Your TypeScript Reduce Logic for Schedule Display
Hey there! As a fellow TypeScript developer, let's work through your reduce logic issues and get your code cleaned up and working correctly. First, let's break down the key problems in your original code, then walk through a fixed, type-safe version.
Main Issues in the Original Code
- Overuse of
any: You're losing all TypeScript type safety here—this makes it hard to catch bugs early, which defeats the purpose of using TS! - Incorrect
mapparameter order: Yourmap((type: any, value: any)has the parameters backwards. The first argument tomapis the array element, not its type. - Mixing React elements and string operations: You can't directly
joinReact elements like<p>closed</p>—this will convert them to[object Object]instead of rendering them properly. - Ambiguous function type: Marking
timeLogicasReact.FCis incorrect here—this is a pure utility function, not a React component.
Fixed, Type-Safe Version
First, let's define clear types to enforce structure, then rewrite the logic properly:
import React from 'react'; // Define a type for each time entry (open/close with timestamp) type TimeEntry = { type: 'open' | 'close'; value: number; }; // Define the shape of your input object: date strings mapped to time entry arrays type DaySchedule = Record<string, TimeEntry[]>; // Date converter with explicit types (no more `any`!) const dateConverter = (sec: number): string => new Date(sec * 1000).toLocaleString('en-US', { hour: 'numeric', hour12: true }); // Refactored utility function (not a React component!) export const getDaySchedules = (schedule: DaySchedule): Record<string, React.ReactNode> => { return Object.keys(schedule).reduce((acc, day, idx, src) => { const dayEntries = schedule[day]; // Handle closed days if (dayEntries.length === 0 || (dayEntries.length === 1 && dayEntries[0].type === 'close')) { acc[day] = <p>closed</p>; return acc; } // Skip the first entry if it's a "close" type const skipFirst = dayEntries[0].type === 'close' ? 1 : 0; const filteredEntries = dayEntries.slice(skipFirst); // Extract time strings and track if we end on an "open" state let isOpen = false; const timeStrings = filteredEntries.map(entry => { isOpen = entry.type === 'open'; return dateConverter(entry.value); }); // If we're still open, add the next day's first close time if (isOpen) { const nextDay = src[(idx + 1) % src.length]; const nextDayFirstEntry = schedule[nextDay][0]; // Add a safety check to avoid errors if next day's first entry isn't close if (nextDayFirstEntry?.type === 'close') { timeStrings.push(dateConverter(nextDayFirstEntry.value)); } } // Format time strings into groups (open - close, open - close, etc.) const timeGroups: string[] = []; for (let i = 0; i < timeStrings.length; i += 2) { timeGroups.push(timeStrings.slice(i, i + 2).join(' - ')); } const formattedSchedule = timeGroups.join(', '); // Store the final React element for this day acc[day] = <p>{formattedSchedule}</p>; return acc; }, {} as Record<string, React.ReactNode>); };
Key Improvements Explained
- Type Safety: We've replaced every
anywith explicit types, so TypeScript will catch mistakes like passing the wrong data structure or accessing undefined properties. - Fixed
mapLogic: Now we correctly iterate over eachTimeEntryobject, accessing itstypeandvalueproperties properly. - Proper React Handling: We avoid mixing React elements with string operations—instead, we build our time strings first, then wrap them in a
<p>tag once they're formatted. - Clearer Grouping: Instead of using a regex replace to format times, we use a simple loop to group open/close pairs, which is easier to read and debug.
- Error Prevention: Added a check to make sure we only add the next day's close time if that entry actually exists and is a "close" type.
- Correct Function Type: Renamed the function to
getDaySchedules(more semantic) and removed the incorrectReact.FCtype, since this is a utility function, not a component.
内容的提问来源于stack exchange,提问作者Taab
相关产品推荐
相关产品推荐

