How to provide both generic type parameter and argument to a function without utilizing default type parameter

28 Views Asked by At

I've created a function that takes two type parameters and a single argument. The single argument provided sets one of the type parameters. The other type parameter is optional.

The problem is that once the first type parameter is explicitly set, the second type parameter no longer utilizes the provided argument. Instead, it uses the default type provided (of which needs to exist since optional type parameters cannot be followed by required parameters).

I've created this example (TypeScript Playground link) to demonstrate the problem that I'm facing. Is this a limitation in TypeScript or am I overlooking a potential solution?

type Options<
  Lorem extends string|number,
  Ipsum extends string|number
> = {
  lorem?: Lorem
  ipsum?: Ipsum
}

// This is the intended interface for the function
function someLibrary<
  Modify extends Record<string, unknown> = {},
  Provided extends Options<any, any> = Options<any, any>
>(options: Provided) {
  return new Proxy(options, {}) as Modify & Provided
}

// A: works as expected
const a = someLibrary({
  lorem: "test",
  ipsum: 123
})

// B: `Provided` type is no longer utilized, defaults to fallback generic even though it's provided in arguments
const b = someLibrary<{ hi: "there" }>({
  lorem: "test",
  ipsum: 123
})

// C: Technically works but is confusing for end-users who don't know why option B doesn't work
const options = {
  lorem: "test",
  ipsum: 123
}
const c = someLibrary<{ hi: "there" }, typeof options>(options)

Am I hitting a limitation of TypeScript or am I overlooking a potential solution? If this is not possible, is there an equivalent way of accomplishing this?

0

There are 0 best solutions below