如何在 Typescript 中深度扁平化界面?

2023-12-09

例如:

interface a {
  name: string 
  nested: {
    lastName: string 
    nested: {
      age: number
    }
  }
}

我希望它变成:

interface b {
  name: string 
  lastName: string 
  age: number
}

接口值将是动态的,所以我可能需要某种递归解决方案

我最终只得到了有限的解决方案


这是使用映射和条件类型的解决方案:FlattenPairs构造一个像对的并集['name', string] | ['lastName', string] | ['age', number], then Flatten将其转换为对象类型。我假设嵌套属性不一定全部命名nested(并且不一定具有可预测的属性名称),因此类型Primitive需要作为递归的基本情况。

type Primitive = string | number | boolean
type FlattenPairs<T> = {[K in keyof T]: T[K] extends Primitive ? [K, T[K]] : FlattenPairs<T[K]>}[keyof T] & [PropertyKey, Primitive]
type Flatten<T> = {[P in FlattenPairs<T> as P[0]]: P[1]}

Example:

interface TestInterface {
  name: string 
  nested: {
    lastName: string 
    nested: {
      age: number
    }
  }
}

// {age: number, lastName: string, name: string}
type Test = Flatten<TestInterface>

游乐场链接

助手类型FlattenPairs如果嵌套属性名称已知,则可以用稍微简单的方式编写:

type FlattenPairs<T> = {[K in keyof T]: K extends 'nested' ? FlattenPairs<T[K]> : [K, T[K]]}[keyof T]

游乐场链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Typescript 中深度扁平化界面? 的相关文章

随机推荐