Angular's `ValidationErrors` type is `{ [key: string]: any }`, which means a validator can attach any shape under any key and the type system will not stop a consumer from misreading it — the safety has to be built by convention, not inferred. Declaring `DateRangeErrors` as a named interface and constructing the exact literal shape it describes before returning it turns the validator's contract into something a code reviewer or future refactor can check by eye, and `readRangeError`'s return type documents precisely what shape callers should expect back from `form.errors?.['rangeInverted']`, even though `errors` itself stays untyped at the framework boundary.
import { FormGroup, FormControl, ValidatorFn, ValidationErrors } from '@angular/forms';interface DateRangeErrors {rangeInverted: { start: string; end: string };}function dateRangeValidator(): ValidatorFn {return (group): ValidationErrors | null => {const start = group.get('start')?.value as string | null;const end = group.get('end')?.value as string | null;if (!start || !end) {return null;}if (new Date(start) > new Date(end)) {const error: DateRangeErrors = {rangeInverted: { start, end },};return error;}return null;};}const form = new FormGroup({start: new FormControl<string | null>(null),end: new FormControl<string | null>(null),},{ validators: dateRangeValidator() },);function readRangeError(): DateRangeErrors['rangeInverted'] | undefined {return form.errors?.['rangeInverted'];}