Typescript如何编写嵌套keyof

问题描述 投票:0回答:1

我有以下代码;

class Transform<T> {
  constructor(private value: T) {}
}


class Test<T extends object> {
  constructor(private a: T) {}

  transform(): { [K in keyof T]: Transform<T[K]> } {
    // functionality omitted
    return this.a as any;
  }
}

const test = new Test({
    a: '',
    b: {
      c: '',
      d: {
          v: ''
      }
    }
})

const transformed = test.transform();

问题是transform方法的返回类型是:

const transformed: {
    a: Transform<string>;
    b: Transform<{
        c: string;
        d: {
            v: string;
        };
    }>;
}

但是我想要的是每个键都是Transform类型:

const transformed: {
    a: Transform<string>;
    b: Transform<{
        c: Transform<string>;
        d: Transform<{
            v: Transform<string>;
        }>;
    }>;
}

有没有一种方法可以通过TS实现?

typescript
1个回答
0
投票

当然。尝试这样的条件递归类型:

type Transformed<T> = {
  [K in keyof T]:
    T[K] extends object
      ? Transform<Transformed<T[K]>>
      : Transform<T[K]>
};

将其用作transform()的返回类型。

class Test<T extends object> {
  constructor(private a: T) {}

  transform(): Transformed<T> {
    // functionality omitted
    return this.a as any;
  }
}

结果:

/**
 * @returns
 *
 * {
 *    a: Transform<string>;
 *    b: Transform<{
 *        c: Transform<string>;
 *        d: Transform<{
 *            v: Transform<string>;
 *        }>;
 *    }>;
 * }
 *
 */
const transformed = test.transform();

注意:某些IDE(例如Visual Studio Code)可能不显示扩展的返回类型。如果要确保我的解决方案确实是您所要的,请使用Compact这样的帮助程序类型,以便使返回类型完整显示。

/**
 * @see https://github.com/microsoft/TypeScript/issues/14829#issuecomment-320754731
 */
type Compact<T> = {} & { [P in keyof T]: T[P] };

type Transformed<T> = Compact<{
  [K in keyof T]:
    T[K] extends object
      ? Transform<Transformed<T[K]>>
      : Transform<T[K]>
}>;

现在,它看起来将完全符合您的要求。希望能有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.