0

Let say, I have this :

const keys = ["name","age"] as const;
type values = [string, number];

const obj : Object<keys,values> = {
    name : "foo", age : 20
} // as Map<keys,values> valid !

const obj2 : Object<keys,values> = {
    name : "foo"
} // as Map<keys,values> error, age is missing!


const obj3 : Object<keys,values> = {
    name : "foo", age : null
} // as Map<keys,values> error, age is not a number!

I would like to create an object type from arrays of keys and values. How can I do it ?

justcodin
  • 857
  • 7
  • 17

2 Answers2

1

You have two problems here:

  1. Object type is not what you want here. Object in TS represent any non-primitive type, and it's not generic: https://www.typescriptlang.org/docs/handbook/basic-types.html#object

  2. Plain JS object is of a different type than Map object, although they both inherit from the Object prototype.

Solution:

// Define correct type for your object
type MyObject = {
  'name': string;
  'age': number;
}

const obj: MyObject  = {
  name: "foo",
  age: 20
}

// Create Map from object
const map = new Map(Object.entries(obj));

Now map is automatically inferred as Map<string, string | number>

Edgar
  • 898
  • 2
  • 12
  • 36
0

Copy-pasted from Zip two types and make object type?

type keys = ['name', 'age']
type values = [string, number]

type ZipTuple<T extends readonly any[], U extends readonly any[]> = {
  [K in keyof T]: [T[K], K extends keyof U ? U[K] : never]
}

type KeyValTuplesToObject<K extends readonly PropertyKey[], V extends readonly any[]> = ZipTuple<
  K,
  V
>[number] extends infer Z
  ? [Z] extends [[any, any]]
    ? { [P in Z[0]]: Extract<Z, [P, any]>[1] }
    : never
  : never

type Obj = KeyValTuplesToObject<keys, values>

const obj: Obj = {
  name: 'foo',
  age: 20
} // as Map<keys,values> valid !

const obj2: Obj = {
  name: 'foo'
} // as Map<keys,values> error, age is missing!

const obj3: Obj = {
  name: 'foo',
  age: null
} // as Map<keys,values> error, age is not a number!


Pritam Kadam
  • 2,388
  • 8
  • 16