我有以下代码;
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实现?
当然。尝试这样的条件递归类型:
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]>
}>;
现在,它看起来将完全符合您的要求。希望能有所帮助!