typescript - 更改深层嵌套对象结构中的值类型

标签 typescript typescript-generics

我需要递归地遍历数据结构并创建一个 type,它根据条件将一些字段更改为不同的类型。

基于以下结构,我需要创建一个类型 (Result),其中所有 A 类型都替换为 B 类型。

class A{}
class B{}

const data = {
    propA:new AA,
    propB:true,
    nested:{
        propC:new AA,
        propD:false
    }
}

// something like:
type Replace<typeof data, A, B>

// result
type Result = {
    propA:B,
    propB:boolean,
    nested:{
        propC:B
        propD:boolean
    }

}

最佳答案

您可以使用映射类型执行此操作,但请记住,匹配是基于对象结构而不是类名,因此当您'针对 A

Replace 类型可以定义为

type Replace<T, From, To> = T extends (...args: any[]) => any ? T : {
  [K in keyof T]: 
    [T[K], From] extends [From, T[K]] ? To : Replace<T[K], From, To>
}

第一个条件是保留任何方法/函数属性,因为映射类型会将它们转换为 {}。映射类型本身处理每个键,并检查值是否扩展了 From 类型和 From 类型扩展了值类型,以确保相等。如果两者相等,则将值替换为 To,否则将递归调用 Replace

这是一个转换示例:

class A{}
class B{b = 42}
class C{}

const data = {
    propA: new A(),
    propBool: true,
    propC: new C(),
    nested:{
        propA: new A(),
        propBool: false
    },
    f: () => 42
}

type Result = Replace<typeof data, A, B>
// type Result = {
//     propA: B;
//     propBool: boolean;
//     propC: B;
//     nested: {
//         propA: B;
//         propBool: boolean;
//     };
//     f: () => number;
// }

TypeScript playground

关于typescript - 更改深层嵌套对象结构中的值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67170249/

相关文章:

typescript - 如何设置 typescript 编译器 (tsc) 的默认目标 es 版本?

typescript - 在 Nest.js 中记录请求/响应

typescript - 根据参数从映射类型返回类型

node.js - 如何从依赖项的依赖项导入接口(interface)

javascript - 具有动态内容的 Angular 通用更新元标记

typescript - 如何修复 "Type ' BaseCtor' 不可分配给类型 'T'“同时使用带有默认参数的泛型

Typescript - 为什么没有相应地强制实现接口(interface)

typescript - typescript 无法理解通用 typescript 函数中的返回类型

javascript - 更改存储为十六进制整数的颜色的单个 channel (RGB)

typescript - 如何避免在 Typescript 中分布多个泛型类型参数?