我正在尝试为一个类编写一个 unwrap
方法,该类包含一个值,或者一个具有内部值的实例:
class Identity<T> {
private readonly value: T;
constructor(value: T) {
this.value = value;
}
static of<T>(value: T): Identity<T> {
return new Identity(value);
}
join(): T { // which return type should go here?
if (this.value instanceof Identity) {
return this.value.join();
}
return this.value;
}
}
这是测试:
const one = Identity.of(Identity.of(Identity.of(123)));
const result: number = one.join();
expect(result).toEqual(123);
谢谢大家!!
最佳答案
您可以更改类型参数 T
, 所以它总是完全嵌套的类型:
class Identity<T> {
private readonly value: T | Identity<T>;
constructor(value: Identity<T>);
constructor(value: T);
constructor(value: any) {
this.value = value;
}
static of<T>(value: Identity<T>): Identity<T>;
static of<T>(valud: T): Identity<T>;
static of<T>(value: T | Identity<T>) {
return new Identity(value);
}
join(): T {
if (this.value instanceof Identity) {
return this.value.join();
}
return this.value;
}
}
const one = Identity.of(Identity.of(Identity.of(123)));
const result: number = one.join();
const result2 = new Identity(new Identity(new Identity(321)));
// Identity<number>
我建议使用上述方法,因为它似乎提供了您真正想要的功能。
如果你需要类型T
实际上是一个嵌套的 Identity<Identity<...>>
仍然有可能,如果 value
是公开的,我们可以执行以下操作:
class Identity<T> {
public readonly value: T;
constructor(value: T) {
this.value = value;
}
static of<T>(value: T): Identity<T> {
return new Identity(value);
}
public join(): IdentityJoinResult<T> {
if (this.value instanceof Identity) {
return this.value.join();
}
return this.value as IdentityJoinResult<T>;
}
}
type IdentityJoinResult<T> =
T extends Identity<any>
? { [Key in keyof T]: IdentityJoinResult<T[Key]> }["value"]
: T
;
const one = Identity.of(Identity.of(Identity.of(123)));
const result: number = one.join();
const result2 = new Identity(new Identity(new Identity(321))).join();
但是如果你改变value
要私有(private)化,您会注意到您不再能够通过类型签名中的“值”进行索引,因此我们解决这个问题的最后一件事是将我们的类型逻辑推迟到一个单独的公共(public)接口(interface),我们可以从输入:
class Identity<T> {
private readonly value: T;
constructor(value: T) {
this.value = value;
}
static of<T>(value: T): Identity<T> {
return new Identity(value);
}
public join(): IdentityJoinResult<T> {
if (this.value instanceof Identity) {
return this.value.join();
}
return this.value as IdentityJoinResult<T>;
}
}
interface NestedIdentity<T> {
_value: T extends Identity<infer U> ? NestedIdentity<U> : T;
}
type NestedIdentityValue<T> =
T extends NestedIdentity<any>
? { [Key in keyof T]: NestedIdentityValue<T[Key]> }["_value"]
: T
;
type IdentityJoinResult<T> = NestedIdentityValue<NestedIdentity<T>>;
const one = Identity.of(Identity.of(Identity.of(123)));
const result: number = one.join();
const result2 = new Identity(new Identity(new Identity(321))).join();
关于typescript - 递归函数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58563611/