简体   繁体   English

使用与其他密钥相同的密钥声明 object

[英]Declare object with same keys as other

I want to declare a mapping of one object to another.我想声明一个 object 到另一个的映射。

The first object can have any string keys and values of a generic type.第一个 object 可以具有任何字符串键和泛型类型的值。

I want to map this object with the same keys, and the types of the values can be anything (but nice would be if I could extract them from the generic).我想 map 这个 object 使用相同的键,值的类型可以是任何东西(但如果我能从通用中提取它们就好了)。 Specifically these are properties of a class and the first is passed in the constructor.具体来说,这些是 class 的属性,第一个在构造函数中传递。

class C {
  ob1: {
    [key: string]: Wrapper<any>
  };
  ob2; // should have the same keys as ob1

  constructor(o?: { [key: string]: Wrapper<any> }) {
    this.ob1 = o;
    // map ob2 from o
  }
}

I think the way to do this is to make C itself a generic class with a type parameter T corresponding to either the type of ob1 or ob2 , and then use mapped types to express "same keys but different/related values".我认为这样做的方法是使C本身成为通用class ,其类型参数T对应于ob1ob2的类型,然后使用映射类型来表示“相同的键但不同/相关的值”。 For example:例如:

type MappedWrapper<T> = { [K in keyof T]: Wrapper<T[K]> }
class C<T> {
  ob1: MappedWrapper<T>
  ob2: T;
  constructor(o: MappedWrapper<T>) { // made param required here
    this.ob1 = o;
    this.ob2 = mapUnwrap(o); // some function that unwraps properties
  }
}

Here we say that T is the type of ob2 , while ob1 has the type MappedWrapper<T> , a mapped type where each property of ob1 is mapped to a Wrapper -version.这里我们说Tob2的类型,而ob1的类型MappedWrapper<T> ,这是一种映射类型,其中ob1的每个属性都映射到Wrapper版本。


Depending on the implementation and declaration of Wrapper and related types, such as:取决于Wrapper和相关类型的实现和声明,例如:

type Wrapper<T> = { x: T };
function wrap<T>(x: T): Wrapper<T> {
  return { x };
}
function unwrap<T>(x: Wrapper<T>): T {
  return x.x;
}
function mapUnwrap<T>(x: MappedWrapper<T>): T {
  return Object.fromEntries(Object.entries(x).map(([k, v]) => [k, unwrap(v)])) as any as T;
}

you can verify that this works as expected:您可以验证这是否按预期工作:

const c = new C({ a: wrap(123), b: wrap("hello"), c: wrap(true) });
/* const c: C<{ a: number; b: string; c: boolean;}> */

c.ob1.a.x.toFixed(); // no error
c.ob2.b.toUpperCase(); // no error

Playground link to code Playground 代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM