有没有一种方法可以将Map <K,V>类型转换为Object类型?

时间:2020-09-19 11:01:02

标签: javascript typescript

让我说:

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!

我想从键和值的数组创建对象类型。我该怎么办?

2 个答案:

答案 0 :(得分:1)

您在这里有两个问题:

  1. Object类型不是您想要的。 TS中的Object代表任何非原始类型,并且不是通用类型:https://www.typescriptlang.org/docs/handbook/basic-types.html#object

  2. 普通JS对象的类型与Map对象不同,尽管它们都继承自Object原型。

解决方案:

// 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));

现在map被自动推断为Map<string, string | number>

答案 1 :(得分:0)

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!