alibaba / pont

🌉数据服务层解决方案
MIT License
3.04k stars 251 forks source link

处理循环嵌套类型 #428

Closed sunlho closed 6 months ago

sunlho commented 6 months ago
export class Submit {

  /** 可操作人集合 */
  principals?: Array<defs.agent.Submit>

}

当生成这种嵌套类型时,在一种循环处理的类型中会出现错误


type NestedPath<T extends 'array' | 'object', P, C = undefined> = `${P & string}${T extends 'array' ? `[${number}]` : ''}${C extends string
  ? `.${C}`
  : ''}`

type DeepNested<K extends string, V> = V extends object[]
  ? NestedPath<'array', K, DeepPath<V[number]> | undefined>
  : V extends unknown[]
  ? NestedPath<'array', K>
  : V extends object
  ? NestedPath<'object', K, DeepPath<V>>
  : never

type FilterObject<T> = T extends object[] ? T[number] : T extends unknown[] ? never : T extends object ? T : never

type IsAny<T> = 0 extends T & 1 ? true : false

type DeepPath<T extends object> = {
  [Q in keyof T]-?: Q | DeepNested<Q & string, NonNullable<T[Q]>>
}[keyof T]
type A = DeepPath<Submit>
const a: A = "principals"

//error TS2615: Type of property 'principals' circularly references itself in mapped type '{ [Q in keyof Submit]-?: Q | DeepNested<Q & string, NonNullable<Submit[Q]>>; }'.

这使我不得不手动处理类型

interface Submit extends Omit<defs.agent.Submit, 'principals'> {
  principals: Omit<defs.agent.Submit, 'principals'>
}

我想问的是我可不可以在生成时自动处理嵌套类型

export class Submit {

  /** 可操作人集合 */
  principals?: Array<Omit<defs.agent.Submit, 'principals'>>

}
z979054461 commented 6 months ago

看一下定制化pont:https://github.com/alibaba/pont/blob/master/docs/customizedPont.md

试试覆盖这个方法?还有getInterfaceContent image

sunlho commented 6 months ago

我重写了getBaseClassInDeclaration,用正则进行了替换

const handleLoopType = (text: string, baseName: string, propName: string) => {
  const reg = new RegExp(`defs\\..*\\.${baseName}`)
  const arr = reg.exec(text)
  if (arr?.length) {
    const n = arr[0]
    return text.replace(n, `Omit<${n}, '${propName}'>`)
  }
  return text
}

getBaseClassInDeclaration(base: BaseClass) {
   //其他代码...
    return `class ${base.name} {
          ${base.properties
            .map((prop) => handleLoopType(prop.toPropertyCode(Surrounding.typeScript, true), base.name, prop.name))
            .join('\n')}
        }
      `
}