Merged in chore/update-eslint-configs (pull request #2812)

chore: Extend eslint configs from @typescript-eslint/recommended

* Change to typescript recommended in scandic-web

* Remove comment

* Change to recommended ts config in partner-sas

* Change to recommended ts lint config in booking-flow


Approved-by: Linus Flood
This commit is contained in:
Anton Gunnarsson
2025-09-17 07:55:11 +00:00
parent e6d5c45ca7
commit 5a86cbaafe
42 changed files with 74 additions and 46 deletions

View File

@@ -9,7 +9,7 @@ import { getLang } from "@/i18n/serverContext"
import { ClientComponent } from "../../../components/ClientComponent" import { ClientComponent } from "../../../components/ClientComponent"
type SearchParams<S = {}> = { type SearchParams<S = object> = {
searchParams: Promise<S & { [key: string]: string }> searchParams: Promise<S & { [key: string]: string }>
} }

View File

@@ -13,7 +13,7 @@ export default async function PaymentCallbackPage(
logger.debug(`[payment-callback] callback started`) logger.debug(`[payment-callback] callback started`)
const lang = params.lang const lang = params.lang
let userAccessToken = null const userAccessToken = null
// TODO fix when auth is implemented // TODO fix when auth is implemented
// const session = await auth() // const session = await auth()
// if (isValidSession(session)) { // if (isValidSession(session)) {

View File

@@ -29,6 +29,7 @@ export function trackOpenSidePeek(input: {
console.warn("TODO: Implement trackOpenSidePeek", { input }) console.warn("TODO: Implement trackOpenSidePeek", { input })
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function trackGenericEvent(data: any) { export function trackGenericEvent(data: any) {
console.warn("TODO: Implement trackGenericEvent", { data }) console.warn("TODO: Implement trackGenericEvent", { data })
} }

View File

@@ -13,7 +13,10 @@ const compat = new FlatCompat({
export default defineConfig([ export default defineConfig([
{ {
extends: compat.extends("next/core-web-vitals", "plugin:import/typescript"), extends: compat.extends(
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended"
),
plugins: { plugins: {
"simple-import-sort": simpleImportSort, "simple-import-sort": simpleImportSort,
"@typescript-eslint": typescriptEslint, "@typescript-eslint": typescriptEslint,

View File

@@ -10,7 +10,7 @@ import type { PageArgs } from "@/types/params"
export { generateMetadata } from "@/utils/metadata/generateMetadata" export { generateMetadata } from "@/utils/metadata/generateMetadata"
export default async function DestinationCityPagePage( export default async function DestinationCityPagePage(
props: PageArgs<{}, { view?: "map"; filterFromUrl?: string }> props: PageArgs<object, { view?: "map"; filterFromUrl?: string }>
) { ) {
const searchParams = await props.searchParams const searchParams = await props.searchParams
return ( return (

View File

@@ -10,7 +10,7 @@ import type { PageArgs } from "@/types/params"
export { generateMetadata } from "@/utils/metadata/generateMetadata" export { generateMetadata } from "@/utils/metadata/generateMetadata"
export default async function DestinationCountryPagePage( export default async function DestinationCountryPagePage(
props: PageArgs<{}, { view?: "map"; filterFromUrl?: string }> props: PageArgs<object, { view?: "map"; filterFromUrl?: string }>
) { ) {
const searchParams = await props.searchParams const searchParams = await props.searchParams
return ( return (

View File

@@ -13,7 +13,7 @@ import type { PageArgs } from "@/types/params"
export { generateMetadata } from "@/utils/metadata/generateMetadata" export { generateMetadata } from "@/utils/metadata/generateMetadata"
export default async function HotelPagePage( export default async function HotelPagePage(
props: PageArgs<{}, { subpage?: string; view?: "map" }> props: PageArgs<object, { subpage?: string; view?: "map" }>
) { ) {
const searchParams = await props.searchParams const searchParams = await props.searchParams
const hotelPageData = await getHotelPage() const hotelPageData = await getHotelPage()

View File

@@ -9,7 +9,7 @@ import type { NextSearchParams, PageArgs } from "@/types/params"
export { generateMetadata } from "@/utils/metadata/generateMetadata" export { generateMetadata } from "@/utils/metadata/generateMetadata"
export default async function StartPagePage( export default async function StartPagePage(
props: PageArgs<{}, NextSearchParams> props: PageArgs<object, NextSearchParams>
) { ) {
const searchParams = await props.searchParams const searchParams = await props.searchParams
const booking = parseBookingWidgetSearchParams(searchParams) const booking = parseBookingWidgetSearchParams(searchParams)

View File

@@ -119,6 +119,7 @@ export async function GET(
logger.debug(`[login] final redirectUrl: ${redirectTo}`) logger.debug(`[login] final redirectUrl: ${redirectTo}`)
/** Record<string, any> is next-auth typings */ /** Record<string, any> is next-auth typings */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const params: Record<string, any> = { const params: Record<string, any> = {
ui_locales: contextParams.lang, ui_locales: contextParams.lang,
scope: [ scope: [

View File

@@ -8,7 +8,7 @@ import { getLang } from "@/i18n/serverContext"
import type { NextSearchParams, PageArgs } from "@/types/params" import type { NextSearchParams, PageArgs } from "@/types/params"
export default async function BookingWidgetDestinationCityPage( export default async function BookingWidgetDestinationCityPage(
props: PageArgs<{}, NextSearchParams> props: PageArgs<object, NextSearchParams>
) { ) {
const searchParams = await props.searchParams const searchParams = await props.searchParams

View File

@@ -8,7 +8,7 @@ import { getLang } from "@/i18n/serverContext"
import type { NextSearchParams, PageArgs } from "@/types/params" import type { NextSearchParams, PageArgs } from "@/types/params"
export default async function BookingWidgetHotelPage( export default async function BookingWidgetHotelPage(
props: PageArgs<{}, NextSearchParams & { subpage?: string }> props: PageArgs<object, NextSearchParams & { subpage?: string }>
) { ) {
const searchParams = await props.searchParams const searchParams = await props.searchParams

View File

@@ -29,7 +29,7 @@ export function LinkAccountForm({
}) { }) {
const router = useRouter() const router = useRouter()
const params = useParams<LangParams>() const params = useParams<LangParams>()
let [isPending, startTransition] = useTransition() const [isPending, startTransition] = useTransition()
const intl = useIntl() const intl = useIntl()
const form = useForm<LinkAccountForm>({ const form = useForm<LinkAccountForm>({
defaultValues: { defaultValues: {

View File

@@ -13,7 +13,7 @@ import type {
} from "@/types/params" } from "@/types/params"
export default async function ContentTypePage( export default async function ContentTypePage(
props: PageArgs<LangParams & ContentTypeWebviewParams & UIDParams, {}> props: PageArgs<LangParams & ContentTypeWebviewParams & UIDParams>
) { ) {
const params = await props.params const params = await props.params

View File

@@ -63,7 +63,11 @@ export function getInitialState({
} }
} }
export function reducer(state: any, action: OverviewTableReducerAction) { export function reducer(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
state: any,
action: OverviewTableReducerAction
) {
switch (action.type) { switch (action.type) {
case OverviewTableActionsEnum.SET_SELECTED_LEVEL_A_MOBILE: case OverviewTableActionsEnum.SET_SELECTED_LEVEL_A_MOBILE:
return { return {

View File

@@ -28,6 +28,7 @@ export default function TableBlock({ data }: TableBlockProps) {
accessorKey: col.id, accessorKey: col.id,
header: col.header, header: col.header,
size: col.width, size: col.width,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cell: (info: any) => ( cell: (info: any) => (
<div dangerouslySetInnerHTML={{ __html: info.getValue() }} /> <div dangerouslySetInnerHTML={{ __html: info.getValue() }} />
), ),

View File

@@ -17,6 +17,7 @@ export default function DialogshiftWidgetClient({
widgetId, widgetId,
language, language,
}: DialogshiftWidgetClientProps) { }: DialogshiftWidgetClientProps) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const dialogshiftRef = useRef<any>(null) const dialogshiftRef = useRef<any>(null)
useEffect(() => { useEffect(() => {

View File

@@ -42,6 +42,7 @@ import type { RenderOptions } from "@/types/rte/option"
function extractPossibleAttributes(attrs: Attributes | undefined) { function extractPossibleAttributes(attrs: Attributes | undefined) {
if (!attrs) return {} if (!attrs) return {}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const props: Record<string, any> = {} const props: Record<string, any> = {}
if (attrs.id) { if (attrs.id) {
props.id = attrs.id props.id = attrs.id
@@ -601,7 +602,7 @@ export const renderOptions: RenderOptions = {
className?: string, className?: string,
id?: string id?: string
) => { ) => {
let props = { const props = {
className, className,
id, id,
} }
@@ -614,9 +615,6 @@ export const renderOptions: RenderOptions = {
if (className) { if (className) {
if (hasAvailableULFormat(className)) { if (hasAvailableULFormat(className)) {
// @ts-ignore: We want to set css modules classNames even if it does not correspond
// to an existing class in the module style sheet. Due to our css modules plugin for
// typescript, we cannot do this without the ts-ignore
props.className = styles[className] props.className = styles[className]
} }
} }

View File

@@ -36,6 +36,7 @@ export function nodeChildrenToHtml(
nodes: RTENode[], nodes: RTENode[],
embeds: EmbedByUid, embeds: EmbedByUid,
fullRenderOptions: RenderOptions fullRenderOptions: RenderOptions
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): any { ): any {
return nodes return nodes
.map((node, i) => { .map((node, i) => {

View File

@@ -176,10 +176,7 @@ export default function Form({ user }: EditFormProps) {
</Button> </Button>
</div> </div>
<form <form
/** /* @ts-expect-error Ignoring since ts doesn't recognize that tRPC parses FormData before reaching the route */
* Ignoring since ts doesn't recognize that tRPC
* parses FormData before reaching the route
* @ts-ignore */
action={editProfile} action={editProfile}
className={styles.form} className={styles.form}
id={formId} id={formId}

View File

@@ -204,6 +204,7 @@ export default function AddAncillaryFlowModal({
) )
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function handleGuaranteePayment(data: AncillaryFormData, packages: any) { function handleGuaranteePayment(data: AncillaryFormData, packages: any) {
const savedCreditCard = savedCreditCards?.find( const savedCreditCard = savedCreditCards?.find(
(card) => card.id === data.paymentMethod (card) => card.id === data.paymentMethod

View File

@@ -7,4 +7,4 @@ export const paymentSchema = z.object({
}), }),
}) })
export interface GuaranteeFormData extends z.output<typeof paymentSchema> {} export type GuaranteeFormData = z.output<typeof paymentSchema>

View File

@@ -95,6 +95,7 @@ export default function TrackGuarantee({
break break
case PaymentCallbackStatusEnum.Cancel: case PaymentCallbackStatusEnum.Cancel:
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
isAncillaryFlow isAncillaryFlow
? trackAncillaryPaymentEvent( ? trackAncillaryPaymentEvent(
"GuaranteeCancelAncillary", "GuaranteeCancelAncillary",
@@ -107,6 +108,7 @@ export default function TrackGuarantee({
break break
case PaymentCallbackStatusEnum.Error: case PaymentCallbackStatusEnum.Error:
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
isAncillaryFlow isAncillaryFlow
? trackAncillaryPaymentEvent( ? trackAncillaryPaymentEvent(
"GuaranteeFailAncillary", "GuaranteeFailAncillary",

View File

@@ -36,7 +36,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
) { ) {
const intl = useIntl() const intl = useIntl()
const { control } = useFormContext() const { control } = useFormContext()
let numberAttributes: HTMLAttributes<HTMLInputElement> = {} const numberAttributes: HTMLAttributes<HTMLInputElement> = {}
if (type === "number") { if (type === "number") {
numberAttributes.onWheel = function (evt: WheelEvent<HTMLInputElement>) { numberAttributes.onWheel = function (evt: WheelEvent<HTMLInputElement>) {
evt.currentTarget.blur() evt.currentTarget.blur()

View File

@@ -15,6 +15,7 @@ interface ReactAriaSelectProps
showRadioButton?: boolean showRadioButton?: boolean
discreet?: boolean discreet?: boolean
isNestedInModal?: boolean isNestedInModal?: boolean
// eslint-disable-next-line @typescript-eslint/no-explicit-any
optionsIcon?: ReactElement<any> optionsIcon?: ReactElement<any>
} }

View File

@@ -13,7 +13,10 @@ const compat = new FlatCompat({
export default defineConfig([ export default defineConfig([
{ {
extends: compat.extends("next/core-web-vitals", "plugin:import/typescript"), extends: compat.extends(
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended"
),
plugins: { plugins: {
"simple-import-sort": simpleImportSort, "simple-import-sort": simpleImportSort,
"@typescript-eslint": typescriptEslint, "@typescript-eslint": typescriptEslint,
@@ -63,7 +66,6 @@ export default defineConfig([
], ],
}, },
], ],
"simple-import-sort/exports": "warn", "simple-import-sort/exports": "warn",
"import/first": "warn", "import/first": "warn",
"import/newline-after-import": "warn", "import/newline-after-import": "warn",

View File

@@ -3,11 +3,11 @@ import type { PageContentTypeEnum } from "@scandic-hotels/trpc/enums/contentType
export type NextSearchParams = { [key: string]: string | string[] | undefined } export type NextSearchParams = { [key: string]: string | string[] | undefined }
export type SearchParams<S = {}> = { export type SearchParams<S = object> = {
searchParams: Promise<S & { [key: string]: string }> searchParams: Promise<S & { [key: string]: string }>
} }
export type Params<P = {}> = { export type Params<P = object> = {
params: Promise<P> params: Promise<P>
} }
@@ -50,7 +50,9 @@ export type PreviewParams = {
live_preview?: string live_preview?: string
} }
export type LayoutArgs<P = undefined> = P extends undefined ? {} : Params<P> export type LayoutArgs<P = undefined> = P extends undefined
? unknown
: Params<P>
export type PageArgs<P = undefined, S = undefined> = LayoutArgs<P> & export type PageArgs<P = undefined, S = undefined> = LayoutArgs<P> &
(S extends undefined ? {} : SearchParams<S>) (S extends undefined ? unknown : SearchParams<S>)

View File

@@ -18,7 +18,10 @@ const packageDir = path.dirname(fileURLToPath(import.meta.url))
export default defineConfig([ export default defineConfig([
{ {
extends: compat.extends("next/core-web-vitals", "plugin:import/typescript"), extends: compat.extends(
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended"
),
plugins: { plugins: {
"simple-import-sort": simpleImportSort, "simple-import-sort": simpleImportSort,
"@typescript-eslint": typescriptEslint, "@typescript-eslint": typescriptEslint,

View File

@@ -13,7 +13,7 @@ import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConf
import type { AdditionalInfoCookieValue } from "../../../../types/components/findMyBooking/additionalInfoCookieValue" import type { AdditionalInfoCookieValue } from "../../../../types/components/findMyBooking/additionalInfoCookieValue"
interface ManageBookingProps extends Pick<BookingConfirmation, "booking"> {} type ManageBookingProps = Pick<BookingConfirmation, "booking">
export default function ManageBooking({ booking }: ManageBookingProps) { export default function ManageBooking({ booking }: ManageBookingProps) {
const intl = useIntl() const intl = useIntl()

View File

@@ -13,7 +13,7 @@ import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConf
import type { AdditionalInfoCookieValue } from "../../../types/components/findMyBooking/additionalInfoCookieValue" import type { AdditionalInfoCookieValue } from "../../../types/components/findMyBooking/additionalInfoCookieValue"
export interface PromosProps extends Pick<BookingConfirmation, "booking"> {} export type PromosProps = Pick<BookingConfirmation, "booking">
export function Promos({ booking }: PromosProps) { export function Promos({ booking }: PromosProps) {
const intl = useIntl() const intl = useIntl()

View File

@@ -90,7 +90,7 @@ export default function BookingWidgetClient({
toDate = now.add(1, "day") toDate = now.add(1, "day")
} }
let selectedLocation = const selectedLocation =
destinationsData?.currentSelection.hotel ?? destinationsData?.currentSelection.hotel ??
destinationsData?.currentSelection.city destinationsData?.currentSelection.city
@@ -199,8 +199,9 @@ export default function BookingWidgetClient({
? JSON.parse(storedBookingCode) ? JSON.parse(storedBookingCode)
: undefined : undefined
initialBookingCode?.remember && if (initialBookingCode?.remember) {
methods.setValue("bookingCode", initialBookingCode) methods.setValue("bookingCode", initialBookingCode)
}
} }
}, [methods, selectedBookingCode]) }, [methods, selectedBookingCode])

View File

@@ -84,7 +84,7 @@ export default function ChildInfoSelector({
] ]
function getAvailableBeds(age: number) { function getAvailableBeds(age: number) {
let availableBedTypes: ChildBed[] = [] const availableBedTypes: ChildBed[] = []
if (age <= 5 && (adults > childrenInAdultsBed || child.bed === 0)) { if (age <= 5 && (adults > childrenInAdultsBed || child.bed === 0)) {
availableBedTypes.push(allBedTypes[0]) availableBedTypes.push(allBedTypes[0])
} }

View File

@@ -63,7 +63,7 @@ export default function GuestsRoomsPickerForm({
const updateHeight = useCallback(() => { const updateHeight = useCallback(() => {
// Get available space for picker to show without going beyond screen // Get available space for picker to show without going beyond screen
const bookingWidget = document.getElementById("booking-widget") const bookingWidget = document.getElementById("booking-widget")
let maxHeight = const maxHeight =
window.innerHeight - window.innerHeight -
(bookingWidget?.getBoundingClientRect().bottom ?? 0) - (bookingWidget?.getBoundingClientRect().bottom ?? 0) -
50 50

View File

@@ -13,4 +13,4 @@ export const paymentSchema = z.object({
guarantee: z.boolean(), guarantee: z.boolean(),
}) })
export interface PaymentFormData extends z.output<typeof paymentSchema> {} export type PaymentFormData = z.output<typeof paymentSchema>

View File

@@ -17,10 +17,9 @@ import { formId } from "../../../Payment/PaymentClient"
import styles from "./bottomSheet.module.css" import styles from "./bottomSheet.module.css"
interface SummaryBottomSheetProps type SummaryBottomSheetProps = PropsWithChildren<{
extends PropsWithChildren<{ isUserLoggedIn: boolean
isUserLoggedIn: boolean }>
}> {}
export default function SummaryBottomSheet({ export default function SummaryBottomSheet({
children, children,

View File

@@ -46,6 +46,7 @@ export async function SelectHotel({
const isAllUnavailable = hotels.every( const isAllUnavailable = hotels.every(
(hotel) => hotel.availability.status !== "Available" (hotel) => hotel.availability.status !== "Available"
) )
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isCityWithCountry = (city: any): city is { country: string } => const isCityWithCountry = (city: any): city is { country: string } =>
"country" in city "country" in city

View File

@@ -84,7 +84,7 @@ export function DesktopSummary({
isUserLoggedIn || selectedRates.rates.some(isBookingCodeRate) isUserLoggedIn || selectedRates.rates.some(isBookingCodeRate)
const mainRoomRate = selectedRates.rates.at(0) const mainRoomRate = selectedRates.rates.at(0)
let mainRoomCurrency = getRoomCurrency(mainRoomRate) const mainRoomCurrency = getRoomCurrency(mainRoomRate)
return ( return (
<> <>

View File

@@ -159,6 +159,7 @@ function CorporateChequeCode({
handleSelectRate, handleSelectRate,
isSelected, isSelected,
}: { }: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
codeProduct: Extract<CodeProduct, { corporateCheque: any }> codeProduct: Extract<CodeProduct, { corporateCheque: any }>
roomIndex: number roomIndex: number
roomTypeCode: string roomTypeCode: string
@@ -329,6 +330,7 @@ function VoucherCode({
handleSelectRate, handleSelectRate,
isSelected, isSelected,
}: { }: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
codeProduct: Extract<CodeProduct, { voucher: any }> codeProduct: Extract<CodeProduct, { voucher: any }>
roomIndex: number roomIndex: number
roomTypeCode: string roomTypeCode: string

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, expect, it } from "vitest" import { describe, expect, it } from "vitest"
import { RateEnum } from "@scandic-hotels/common/constants/rate" import { RateEnum } from "@scandic-hotels/common/constants/rate"

View File

@@ -345,11 +345,10 @@ function getRequestedAdditionalPrice(
} }
} }
interface TRoom type TRoom = Pick<
extends Pick< RoomState["room"],
RoomState["room"], "adults" | "breakfast" | "guest" | "roomFeatures" | "roomRate"
"adults" | "breakfast" | "guest" | "roomFeatures" | "roomRate" >
> {}
interface TRoomCorporateCheque extends TRoom { interface TRoomCorporateCheque extends TRoom {
roomRate: CorporateChequeProduct roomRate: CorporateChequeProduct

View File

@@ -20,6 +20,7 @@ export type TrackingFunctions = {
includePathname?: boolean includePathname?: boolean
roomTypeCode?: string | null roomTypeCode?: string | null
}) => void }) => void
// eslint-disable-next-line @typescript-eslint/no-explicit-any
trackGenericEvent(data: any): void trackGenericEvent(data: any): void
trackLoginClick(position: TrackingPosition & (string & {})): void trackLoginClick(position: TrackingPosition & (string & {})): void
trackPaymentEvent(payment: PaymentEvent): void trackPaymentEvent(payment: PaymentEvent): void

View File

@@ -548,6 +548,7 @@ const getSearchParams = (input: string) => {
return searchParamsToObject(searchParams) return searchParamsToObject(searchParams)
} }
const searchParamsToObject = (searchParams: URLSearchParams) => { const searchParamsToObject = (searchParams: URLSearchParams) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const obj: Record<string, any> = {} const obj: Record<string, any> = {}
for (const [key, value] of searchParams.entries()) { for (const [key, value] of searchParams.entries()) {
obj[key] = value obj[key] = value

View File

@@ -20,6 +20,7 @@ export function parseSearchParams<T extends z.ZodRawShape>(
export function parseSearchParams<T extends z.ZodRawShape>( export function parseSearchParams<T extends z.ZodRawShape>(
searchParams: NextSearchParams, searchParams: NextSearchParams,
options?: ParseOptions<T> options?: ParseOptions<T>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Record<string, any> ): Record<string, any>
/** /**
@@ -49,6 +50,7 @@ export function parseSearchParams<T extends z.ZodRawShape>(
const buildObject = getBuilder(options || {}) const buildObject = getBuilder(options || {})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const resultObject: Record<string, any> = {} const resultObject: Record<string, any> = {}
for (const [key, value] of entries) { for (const [key, value] of entries) {
const paths = key.split(".") const paths = key.split(".")
@@ -80,6 +82,7 @@ function getBuilder<T extends z.ZodRawShape>(options: ParseOptions<T>) {
const typeHints = options.typeHints || {} const typeHints = options.typeHints || {}
return function buildNestedObject( return function buildNestedObject(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj: Record<string, any>, obj: Record<string, any>,
paths: string[], paths: string[],
value: string value: string
@@ -134,6 +137,7 @@ function getBuilder<T extends z.ZodRawShape>(options: ParseOptions<T>) {
} }
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isNotArray(value: any) { function isNotArray(value: any) {
return !value || typeof value !== "object" || !Array.isArray(value) return !value || typeof value !== "object" || !Array.isArray(value)
} }
@@ -157,6 +161,7 @@ type SerializeOptions = {
* Arrays are not merged, they will always replace existing values. * Arrays are not merged, they will always replace existing values.
*/ */
export function serializeSearchParams( export function serializeSearchParams(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj: Record<string, any>, obj: Record<string, any>,
options?: SerializeOptions options?: SerializeOptions
): URLSearchParams { ): URLSearchParams {