export const capitalize = (str: T) => { return (str.charAt(0).toUpperCase() + str.slice(1)) as Capitalize; }; export const isNullOrWhitespace = (value: string | null): value is null => { return value == null || value.trim() === ""; }; export const bestMatch = >( search: string, options: TItem[], by: (item: TItem) => string, ) => { if (options.length === 0) return null; const normalizedSearch = search.toLowerCase().trim(); return options.reduce((best, current) => { const currentMatchIndex = by(current).toLowerCase().indexOf(normalizedSearch); if (currentMatchIndex === -1) return best; if (best === null) return current; const bestMatchIndex = by(best).toLowerCase().indexOf(normalizedSearch); if (currentMatchIndex < bestMatchIndex) return current; if (by(current).length < by(best).length && currentMatchIndex === bestMatchIndex) return current; return best; }, null); };