我正在尝试编写一个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);
谢谢大家!
您可以更改type参数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
为私有,您会注意到您不再能够在类型签名中按“值”进行索引,因此,我们要解决的最后一件事是将类型逻辑推迟到单独的公共接口上,可以从类型确定:
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();
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句