【问题标题】:Typescript: Create recursive mapped type that maps from existing type to string打字稿:创建从现有类型映射到字符串的递归映射类型
【发布时间】:2022-01-06 13:48:39
【问题描述】:

给定一个类型,我如何编写一个递归映射类型,它产生一个具有所有相同键但它们的类型是字符串而不是它们的传入类型的类型?具体来说,我想处理嵌套对象和数组。

type MySourceType = {
  field1 :string,
  field2: number,
  field3: number[],
  field4: Date, 
  field5: {
    nestedField1: number,
    nestedField2: number[]
    nestedField3: Date,
  }
}
type MyDestinationType = MakeAllFieldsString<MySourceType>;

应该让步:

type MyDestinationType = {
    field1 :string,
    field2: string,
    field3: string[],
    field4: string, 
    field5: {
      nestedField1: string,
      nestedField2: string[]
      nestedField3: string,
    }
  }

这适用于常规的“平面”对象,但无法处理嵌套对象和数组

type JsonObject<T> = {[Key in keyof T]: string; }

我也试过这个,但它似乎也没有达到我的预期。

type NestedJsonObject<T> = {
[Key in keyof T]: typeof T[Key] extends object ? JsonObject<T[Key]> : string;
}

【问题讨论】:

  • 第二次尝试中“typeof”在做什么?那里没有错误吗?如果您只是删除typeof,它会开始工作吗?
  • 好收获;我正在尝试不同的变化,这确实是一个错误。但是,如果没有 typeof,它就无法按预期工作......或者至少没有达到我希望的效果
  • 您能否edit 您的问题不包括语法错误,以便您的示例成为minimal reproducible example?另外,由于Date 是您想要成为string 的对象类型,但{a: number} 是您不想 想要成为string 的对象类型,您能解释一下您是如何做到的吗?希望映射能够区分您想要递归到的对象类型与不想递归的对象类型之间的区别?比如,我们可以特例 Date,但这是唯一的吗?

标签: typescript typescript-typings typescript-generics


【解决方案1】:

你可以这样做:

type MySourceType = {
  field1: string;
  field2: number;
  field3: number[];
  field4: Date;
  field5: {
    nestedField1: number;
    nestedField2: number[];
    nestedField3: Date;
  };
};

type Literal = { [k: string]: {} };

type JsonObject<T> = T extends Array<infer U>
  ? U extends Literal
  ? Array<JsonObject<U>>
  : Array<string>
  : T extends Literal
  ? { [Key in keyof T]: JsonObject<T[Key]> }
  : string;

type MyDestinationType = JsonObject<MySourceType>;

TypeScript 游乐场:https://tsplay.dev/WYBlgw

【讨论】:

  • 谢谢!两个问题 - 那里的 Literal 类型有什么作用?第二个问题 - 对象数组变成字符串数组;有解决办法吗?
  • 你的Literal 检查有点奇怪,因为这只是因为MySourceType 是匿名对象类型的类型别名而不是接口。如果传入接口,您认为 OP 是否希望 this 发生?而且,Literal 不会匹配任何可以为空的值,所以this 会发生。不确定这是否是此处所需的行为。
  • 我已经为数组提供了一个修复 @jcalz 你有什么建议作为更好的解决方案?
  • @James 请edit 演示您关心的用例的问题,以便代码中有minimal reproducible example。如果您需要“对象数组”,您应该展示它是什么,这样回答的人就不会做出错误的假设。
  • @GuerricP 没有来自 OP 的关于他们期望在不同的边缘情况下发生什么的详细信息,我不确定。显然,您发布的版本是他们想要的,因为它已被接受,但我确实想知道他们希望在我上面强调的案例中看到什么。
猜你喜欢
  • 2019-11-19
  • 2020-06-07
  • 2019-12-11
  • 2022-12-07
  • 1970-01-01
  • 1970-01-01
  • 2020-10-16
  • 2022-08-17
  • 1970-01-01
相关资源
最近更新 更多