开启noImplicitAny检查时,如何重写TypeScript的for-in循环?
RegisterData (noImplicitAny Compliant) Great question! When noImplicitAny is enabled, using any for nonEmptyData isn’t just a lint error—it strips away all the type safety TypeScript is designed to provide. Let’s rewrite your logic to keep filtering non-empty fields and excluding password, while staying fully type-compliant.
First, let’s define a clear type for our filtered output using TypeScript’s built-in utility types:
// Create a type that excludes the password field from RegisterData type FilteredRegisterData = Omit<RegisterData, 'password'>;
Option 1: Type-Safe for-in Loop
We’ll explicitly type our accumulator and loop keys to avoid any while keeping your original loop structure:
// Example input data const registerData: RegisterData = { email: "arsenii@example.com", password: "mySecurePassword", firstName: "Arsenii" }; // Initialize accumulator with a type that matches our filtered fields (partial allows incremental building) const nonEmptyData: Partial<FilteredRegisterData> = {}; for (const itemId in registerData) { // Assert the key belongs to our filtered type (automatically excludes "password") const key = itemId as keyof FilteredRegisterData; const value = registerData[key]; // Only include fields with non-empty values if (value) { nonEmptyData[key] = value; } } // Optional: If you need a precise type for the final object (no optional fields for present values) const finalFilteredData = nonEmptyData as { [K in keyof FilteredRegisterData]-?: Exclude<FilteredRegisterData[K], undefined>; };
Option 2: Functional Approach with reduce
If you prefer a more modern, functional style, Object.entries and reduce work great while maintaining type safety:
const nonEmptyData = Object.entries(registerData).reduce<Partial<FilteredRegisterData>>( (acc, [key, value]) => { // Skip password and empty values if (key !== "password" && value !== undefined) { acc[key as keyof FilteredRegisterData] = value; } return acc; }, {} // Initialize empty accumulator with the correct type );
Why This Works
Omit<RegisterData, 'password'>creates a type that includes all fields fromRegisterDataexceptpassword, so we never accidentally include the excluded field.Partial<FilteredRegisterData>lets us build the object incrementally (since optional fields likefirstNamemight not be present in the final output).- Using
keyof FilteredRegisterDataensures we only work with valid field names, eliminating arbitrary string keys that would trigger type errors.
This approach keeps your original filtering logic intact while complying with noImplicitAny and preserving TypeScript’s type checks.
内容的提问来源于stack exchange,提问作者Arsenii Fomin

