Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preserve key type when using Object.entries()

Tags:

typescript

Here's an example of my issue (demo in ts playground)

type Tkey = 'foo' | 'bar' | 'defaultKey'

const typedObject: Record<Tkey, Boolean> = {
  'foo': true,
  'bar': false,
  'defaultKey': true
}

// type does not persist string narrowing
const entries = Object.entries(typedObject) // [string, Boolean][]

So key in [key, values] is of type string and not of type Tkey.

demo of resulting type

As a workaround you can manually coerce after the fact, but it'd be nice to define the type during the operation.

const typedEntries = entries as [Tkey, Boolean][]
like image 890
Norfeldt Avatar asked Oct 15 '22 20:10

Norfeldt


1 Answers

You can extend the default typescript lib by adding your own object definition that takes in two generic type params.

Add the following a globals.d.ts file at your project root:

interface ObjectConstructor {
    entries<TKey extends PropertyKey, TVal>(o: Record<TKey,TVal>): [TKey, TVal][];
    keys<TKey extends PropertyKey>(obj: Record<TKey,any>): TKey[];
}

And then use it like this:

const entries = Object.entries<ObjKeys, Boolean>(myObj) // [ObjKeys, Boolean][]
const keys = Object.keys<ObjKeys>(myObj) // ObjKeys[]

Demo in TS Playground

like image 135
KyleMit Avatar answered Oct 18 '22 07:10

KyleMit