diff --git a/packages/rest/__tests__/utils.test.ts b/packages/rest/__tests__/utils.test.ts index 90482b9ad..f924f1791 100644 --- a/packages/rest/__tests__/utils.test.ts +++ b/packages/rest/__tests__/utils.test.ts @@ -58,4 +58,31 @@ describe('makeURLSearchParams', () => { expect([...params.entries()]).toEqual([['foo', 'bar']]); }); }); + + describe('types', () => { + interface TestInput { + foo: string; + } + + test("GIVEN object without index signature THEN TypeScript doesn't raise a type error", () => { + // Previously, `makeURLSearchParams` used `Record` as an input, but that meant that it + // couldn't accept most interfaces, since they don't have an index signature. This test is to make sure + // non-Records can be used without casting. + + const input = { foo: 'bar' } as TestInput; + const params = makeURLSearchParams(input); + + expect([...params.entries()]).toEqual([['foo', 'bar']]); + }); + + test("GIVEN readonly object on a non-readonly generic type THEN TypeScript doesn't raise a type error", () => { + // While `Readonly` type was always accepted in `makeURLSearchParams`, this test is to ensure that we can + // use the generic type and accept `Readonly` rather than only [possibly] mutable `T`. + + const input = Object.freeze({ foo: 'bar' } as TestInput); + const params = makeURLSearchParams(input); + + expect([...params.entries()]).toEqual([['foo', 'bar']]); + }); + }); }); diff --git a/packages/rest/src/lib/utils/utils.ts b/packages/rest/src/lib/utils/utils.ts index 6034fdaa5..dcbcf1bc1 100644 --- a/packages/rest/src/lib/utils/utils.ts +++ b/packages/rest/src/lib/utils/utils.ts @@ -43,7 +43,7 @@ function serializeSearchParam(value: unknown): string | null { * @param options - The options to use * @returns A populated URLSearchParams instance */ -export function makeURLSearchParams(options?: Record) { +export function makeURLSearchParams(options?: Readonly) { const params = new URLSearchParams(); if (!options) return params;