我有一个与此相匹配的特定界面:

interface Example {
  field_a: number | null;
  field_b: readonly string[];
  readonly field_c: string;
  nested: {
   field_d: readonly unknown[]
  }
} 

我想应用一个Mutations 并删除所有只读内容,如下所示:

type Mutable<T> = {
  -readonly [K in keyof T]: T[K] extends Readonly<T[K]> ? Mutable<T[K]> : T[K];
 };

创建一个新的类型Mutable<Example>,将应用Mutate到所有字段,即使它是不需要的,所以如果我悬停在field_a,应用的类型是Mutable<number | null>,这不是我想要的.

我需要最终的结果是如下所示的这个特定的例子(当做Mutable<Example>),但应该是足够的动态处理不同的接口.

type TransformedExample = {
  field_a: number | null;
  field_b: string[];
  field_c: string;
  nested: {
   field_d: unknown[]
  }
} 

提前感谢您的帮助!

推荐答案

听起来您只想迭代对象类型的键,而不是其他类型的键.

如果是这样的话,您只需要再进行一次T extends object形式的条件判断:

type Mutable<T> =
  T extends object
    ? {
      -readonly [K in keyof T]:
        T[K] extends Readonly<T[K]>
          ? Mutable<T[K]>
          : T[K];
    }
    : T

它的工作方式与您预期的一样:

interface Example {
  field_a: number | null;
  field_b: readonly string[];
  readonly field_c: string;
  nested: {
    field_d: readonly unknown[]
  }
}

type TransformedExample = Mutable<Example>

TransformedType被报告为:

type TransformedExample = {
    field_a: number | null;
    field_b: string[];
    field_c: string;
    nested: {
        field_d: unknown[];
    };
}

很漂亮也很干净.

See playground


事实上,您现在可以完全取消T[K] extends Readonly<T[K]>支票,这将大大简化这一点.

type Mutable<T> =
  T extends object
    ? { -readonly [K in keyof T]: Mutable<T[K]> }
    : T

由于您希望每个对象属性都是可变的,因此不必首先判断它是否是只读的.你只是让一切都可变,不管它是如何开始的.

See Playground

Typescript相关问答推荐

Typescript如何从字符串中提取多个文本

React组件数组及其props 的类型定义

如何使打包和拆包功能通用?

JS Redux Devtools扩展不工作

在TypeScrip的数组中判断模式类型

是否可以判断某个类型是否已合并为内部类型?

如何在脚本中输入具有不同数量的泛型类型变量的函数?

17个Angular 的延迟观察.如何在模板中转义@符号?

如何将通用接口的键正确设置为接口的键

设置不允许相同类型的多个参数的线性规则

推断集合访问器类型

基于属性值的条件类型

可以用任意类型实例化,该类型可能与

窄SomeType与SomeType[]

如何将对象的字符串文字属性用作同一对象中的键类型

换行TypeScript';s具有泛型类型的推断数据类型

可以';t使用t正确地索引对象;联合;索引类型

从泛型对象数组构造映射类型

基于参数的 TS 返回类型

使用本机 Promise 覆盖 WinJS Promise 作为 Chrome 扩展内容脚本?