dx_over_dt
dx_over_dt

Reputation: 14318

Cannot apply Array prototype extension to readonly arrays in TypeScript

This is a continuation of Infer shape of result of Object.fromEntries() in TypeScript, though you probably don't need to read it to know what's going on.

I am trying to extend the Array prototype to add a shortcut around Object.fromEntries() if the array is the right shape for it.

// the aforementioned question uses this signature for Object.fromEntries() replacing `this` 
// with a parameter `array`
interface Array<T> {
  objectFromEntries<
    P extends PropertyKey,
    A extends ReadonlyArray<readonly [P, any]>
  >(this: A): { [K in A[number][0]]: Extract<A[number], readonly [K, any]>[1] };
}

This works fine if the array is not readonly but its elements are, but does not work on readonly tuples of arrays.

const works = [['a', 1] as const, ['b', 2] as const];
let obj = works.objectFromEntries();

const doesntWork = [['a', 1], ['b', 2]] as const;
obj = doesntWork.objectFromEntries();
/**
 * Error message:
 *   Property 'objectFromEntries' does not exist on type 'readonly [readonly ["a", 1], readonly ["b", 2]]'. ts(2339)
 */

I've tried unioning A with a bunch of variations, but none of them work.

    objectFromEntries<
      P extends PropertyKey,
      A extends
        ReadonlyArray<readonly [P, any]> |
        Array<readonly [P, any]> |
        ReadonlyArray<[P, any]> |
        Array<[P, any]> |
        readonly [...readonly [P, any][]]
    >(this: A): { [K in A[number][0]]: Extract<A[number], readonly [K, any]>[1] };

Ideas?

TS Playground

Upvotes: 1

Views: 286

Answers (1)

dx_over_dt
dx_over_dt

Reputation: 14318

The solution was simple and obvious. I needed to add the method toReadonlyArray<T> as well.

Upvotes: 1

Related Questions