Allow non-null assertions in tests; refactor two production hotspots to drop them

- eslint.config.js: disable no-non-null-assertion for *.test.ts/tsx and
  tests/** (fixture-driven tests routinely use arr[0]! after a length
  check — signal there is low).
- closestFlight.ts: replace flights.legs[0]! / flights[flights.length-1]!
  with explicit null checks.
- FlightDetailsAccordion.tsx: refactor transition + meal/service
  branches to use local consts narrowed by a preceding truthy check,
  dropping the `leg.transition!.registration!` patterns.

Warning count: 190 → 65. Remaining warnings are pre-existing production-code
non-null assertions spread across the codebase.
This commit is contained in:
2026-04-20 08:24:01 +03:00
parent a982d9a669
commit 5c47498472
3 changed files with 46 additions and 23 deletions
+12
View File
@@ -177,4 +177,16 @@ export default [
], ],
}, },
}, },
// Test files get a looser ruleset: non-null assertions are idiomatic
// when fixtures guarantee presence (`arr[0]!` after an explicit length
// check). Production code keeps the warning; tests don't.
{
files: [
"src/**/*.test.{ts,tsx}",
"tests/**/*.{ts,tsx}",
],
rules: {
"@typescript-eslint/no-non-null-assertion": "off",
},
},
]; ];
+16 -7
View File
@@ -11,13 +11,17 @@
import type { ISimpleFlight, IFlightLeg } from "./types.js"; import type { ISimpleFlight, IFlightLeg } from "./types.js";
function firstLeg(flight: ISimpleFlight): IFlightLeg { function firstLeg(flight: ISimpleFlight): IFlightLeg {
return flight.routeType === "Direct" ? flight.leg : flight.legs[0]!; if (flight.routeType === "Direct") return flight.leg;
const first = flight.legs[0];
if (!first) throw new Error("MultiLeg flight has no legs");
return first;
} }
function lastLeg(flight: ISimpleFlight): IFlightLeg { function lastLeg(flight: ISimpleFlight): IFlightLeg {
return flight.routeType === "Direct" if (flight.routeType === "Direct") return flight.leg;
? flight.leg const last = flight.legs[flight.legs.length - 1];
: flight.legs[flight.legs.length - 1]!; if (!last) throw new Error("MultiLeg flight has no legs");
return last;
} }
function pickTime(flight: ISimpleFlight, isArrival: boolean): string | null { function pickTime(flight: ISimpleFlight, isArrival: boolean): string | null {
@@ -78,9 +82,14 @@ export function findClosestFlightId(
if (!isTodayYyyymmdd(opts.searchDate, now)) { if (!isTodayYyyymmdd(opts.searchDate, now)) {
// For future days, show the first flight; for past days, the last. // For future days, show the first flight; for past days, the last.
const firstMs = parseTimeMs(pickTime(flights[0]!, opts.isArrival)); // We've already short-circuited on `!flights.length` above so both
if (firstMs !== null && nowMs < firstMs) return flights[0]!.id; // ends are defined.
return flights[flights.length - 1]!.id; const first = flights[0];
const last = flights[flights.length - 1];
if (!first || !last) return null;
const firstMs = parseTimeMs(pickTime(first, opts.isArrival));
if (firstMs !== null && nowMs < firstMs) return first.id;
return last.id;
} }
let best: string | null = flights[0]?.id ?? null; let best: string | null = flights[0]?.id ?? null;
@@ -140,38 +140,38 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
const rows: RowDef[] = []; const rows: RowDef[] = [];
if (shouldShowTransition(leg.transition?.registration, leg.status, viewType)) { const registration = leg.transition?.registration;
const item = leg.transition!.registration!; if (registration && shouldShowTransition(registration, leg.status, viewType)) {
rows.push({ rows.push({
id: "registration", id: "registration",
icon: ICON_REGISTRATION, icon: ICON_REGISTRATION,
title: t("DETAILS.REGISTRATION"), title: t("DETAILS.REGISTRATION"),
statusStatus: item.status, statusStatus: registration.status,
body: <TransitionTimes item={item} testId="registration-times" />, body: <TransitionTimes item={registration} testId="registration-times" />,
legacyTestId: "registration-panel", legacyTestId: "registration-panel",
isTransition: true, isTransition: true,
}); });
} }
if (shouldShowTransition(leg.transition?.boarding, leg.status, viewType)) { const boarding = leg.transition?.boarding;
const item = leg.transition!.boarding!; if (boarding && shouldShowTransition(boarding, leg.status, viewType)) {
rows.push({ rows.push({
id: "boarding", id: "boarding",
icon: ICON_BOARDING, icon: ICON_BOARDING,
title: t("DETAILS.BOARDING"), title: t("DETAILS.BOARDING"),
statusStatus: item.status, statusStatus: boarding.status,
body: <TransitionTimes item={item} testId="boarding-times" />, body: <TransitionTimes item={boarding} testId="boarding-times" />,
legacyTestId: "boarding-panel", legacyTestId: "boarding-panel",
isTransition: true, isTransition: true,
}); });
} }
if (shouldShowTransition(leg.transition?.deboarding, leg.status, viewType)) { const deboarding = leg.transition?.deboarding;
const item = leg.transition!.deboarding!; if (deboarding && shouldShowTransition(deboarding, leg.status, viewType)) {
rows.push({ rows.push({
id: "deboarding", id: "deboarding",
icon: ICON_DEBOARDING, icon: ICON_DEBOARDING,
title: t("DETAILS.DEBOARDING"), title: t("DETAILS.DEBOARDING"),
statusStatus: item.status, statusStatus: deboarding.status,
body: <TransitionTimes item={item} testId="deboarding-times" />, body: <TransitionTimes item={deboarding} testId="deboarding-times" />,
legacyTestId: "deboarding-panel", legacyTestId: "deboarding-panel",
isTransition: true, isTransition: true,
}); });
@@ -187,20 +187,22 @@ export const FlightDetailsAccordion: FC<FlightDetailsAccordionProps> = ({ leg, v
body: <AircraftPanel equipment={leg.equipment} />, body: <AircraftPanel equipment={leg.equipment} />,
}); });
} }
if ((leg.equipment.meal?.length ?? 0) > 0) { const meals = leg.equipment.meal;
if (meals && meals.length > 0) {
rows.push({ rows.push({
id: "meal", id: "meal",
icon: ICON_MEAL, icon: ICON_MEAL,
title: t("SHARED.FOOD"), title: t("SHARED.FOOD"),
body: <MealPanel meals={leg.equipment.meal!} />, body: <MealPanel meals={meals} />,
}); });
} }
if ((leg.equipment.aircraft?.actual?.onBoardServices?.length ?? 0) > 0) { const onBoardServices = leg.equipment.aircraft?.actual?.onBoardServices;
if (onBoardServices && onBoardServices.length > 0) {
rows.push({ rows.push({
id: "services", id: "services",
icon: ICON_SERVICES, icon: ICON_SERVICES,
title: t("DETAILS.ON_BOARD_SERVICES"), title: t("DETAILS.ON_BOARD_SERVICES"),
body: <ServicesPanel services={leg.equipment.aircraft!.actual!.onBoardServices!} />, body: <ServicesPanel services={onBoardServices} />,
}); });
} }