feat: Enable TypeScript strict mode

This commit is contained in:
gpt-engineer-app[bot]
2025-11-03 00:58:42 +00:00
parent 061c06be29
commit d126be2908
15 changed files with 308 additions and 68 deletions

View File

@@ -0,0 +1,40 @@
/**
* Type definitions for composite submissions
* Used when creating multiple related entities in a single submission
*/
import type { TempCompanyData } from './company';
/**
* Composite submission structure for park creation with related entities
*/
export interface ParkCompositeSubmission {
park: {
name: string;
slug: string;
description?: string;
park_type: string;
status: string;
opening_date?: string;
closing_date?: string;
location_id?: string;
website_url?: string;
phone?: string;
email?: string;
operator_id?: string | null;
property_owner_id?: string | null;
[key: string]: unknown;
};
new_operator?: TempCompanyData;
new_property_owner?: TempCompanyData;
}
/**
* Generic composite submission content type
* Supports any entity type with optional related entities
*/
export interface CompositeSubmissionContent {
[entityKey: string]: {
[key: string]: unknown;
} | TempCompanyData | undefined;
}

55
src/types/recharts.ts Normal file
View File

@@ -0,0 +1,55 @@
/**
* Type definitions for Recharts payloads
* Provides type-safe alternatives to `any` in chart components
*/
import type { ReactNode } from 'react';
/**
* Generic chart payload item structure
*/
export interface ChartPayloadItem<T = unknown> {
value?: number | string;
name?: string;
dataKey?: string;
color?: string;
fill?: string;
payload?: T;
[key: string]: unknown;
}
/**
* Tooltip content props from Recharts
*/
export interface TooltipProps<T = unknown> {
active?: boolean;
payload?: ChartPayloadItem<T>[];
label?: string | number;
labelFormatter?: (value: unknown, payload: ChartPayloadItem<T>[]) => ReactNode;
formatter?: (
value: number | string,
name: string,
item: ChartPayloadItem<T>,
index: number,
payload: unknown
) => ReactNode;
className?: string;
indicator?: 'line' | 'dot' | 'dashed';
hideLabel?: boolean;
hideIndicator?: boolean;
color?: string;
nameKey?: string;
labelKey?: string;
labelClassName?: string;
}
/**
* Legend content props from Recharts
*/
export interface LegendProps<T = unknown> {
payload?: ChartPayloadItem<T>[];
className?: string;
hideIcon?: boolean;
nameKey?: string;
verticalAlign?: 'top' | 'bottom';
}

View File

@@ -0,0 +1,113 @@
/**
* Type-safe helpers for accessing submission item data
* Provides type guards and type narrowing for Json fields
*/
import type { Json } from '@/integrations/supabase/types';
/**
* Base structure that all item_data objects should have
*/
export interface BaseItemData {
name?: string;
slug?: string;
description?: string;
[key: string]: Json;
}
/**
* Type guard to safely check if Json is an object with a name property
*/
export function hasName(data: Json): data is { name: string } & Record<string, Json> {
return typeof data === 'object' && data !== null && !Array.isArray(data) && 'name' in data && typeof (data as Record<string, Json>).name === 'string';
}
/**
* Type guard to check if Json is a photos array
*/
export function hasPhotos(data: Json): data is { photos: Array<Record<string, Json>> } & Record<string, Json> {
return typeof data === 'object' && data !== null && !Array.isArray(data) && 'photos' in data && Array.isArray((data as Record<string, Json>).photos);
}
/**
* Type guard for manufacturer data
*/
export function hasManufacturer(data: Json): data is { manufacturer_id: string; manufacturer_name: string } & Record<string, Json> {
return (
typeof data === 'object' &&
data !== null &&
!Array.isArray(data) &&
'manufacturer_id' in data &&
'manufacturer_name' in data
);
}
/**
* Type guard for park data
*/
export function hasParkId(data: Json): data is { park_id: string } & Record<string, Json> {
return typeof data === 'object' && data !== null && !Array.isArray(data) && 'park_id' in data;
}
/**
* Type guard for ride data
*/
export function hasRideId(data: Json): data is { ride_id: string } & Record<string, Json> {
return typeof data === 'object' && data !== null && !Array.isArray(data) && 'ride_id' in data;
}
/**
* Type guard for company data
*/
export function hasCompanyId(data: Json): data is { company_id: string } & Record<string, Json> {
return typeof data === 'object' && data !== null && !Array.isArray(data) && 'company_id' in data;
}
/**
* Type guard for ride model data
*/
export function hasRideModelId(data: Json): data is { ride_model_id: string } & Record<string, Json> {
return typeof data === 'object' && data !== null && !Array.isArray(data) && 'ride_model_id' in data;
}
/**
* Safely get name from item_data
*/
export function getItemName(data: Json): string {
if (hasName(data)) {
return data.name;
}
return 'Unnamed';
}
/**
* Safely get photos from item_data
*/
export function getItemPhotos(data: Json): Array<Record<string, Json>> {
if (hasPhotos(data)) {
return data.photos;
}
return [];
}
/**
* Convert Json to a record for form usage
* Only use when you need to pass data to form components
*/
export function jsonToRecord(data: Json): Record<string, Json> {
if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
return data as Record<string, Json>;
}
return {};
}
/**
* Type-safe way to access nested Json properties
*/
export function getProperty<T = Json>(data: Json, key: string): T | undefined {
if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
const obj = data as Record<string, Json>;
return obj[key] as T | undefined;
}
return undefined;
}