防止循环引用的通用方法

huangapple go评论68阅读模式
英文:

Generic that prevents circular references

问题

以下是代码的翻译部分:

是否有一种方法可以创建一个泛型,以防止循环变量?
这应该适用于深度或循环引用类型,不仅仅适用于T本身...

到目前为止,我得到了这个:

export type IsEqual<A, B> =
    (<G>() => G extends A ? 1 : 2) extends
    (<G>() => G extends B ? 1 : 2)
    ? true
    : false;

type DisallowCircular<T> = {
    [K in keyof T]: true extends IsEqual<T[K], T> ? never : T[K]
};

function noCircularAllowed<T extends DisallowCircular<T>>(a: T) {

}

class Foo {
    abc: string;
    circular: Foo;

    constructor() {
        this.abc = "Hello";
        this.circular = this;
    }
}

const foo = new Foo()

noCircularAllowed(foo)

请注意,以上是您提供的代码的翻译部分,不包括问题部分。如果您有任何其他需要翻译的内容,请告诉我。

英文:

Is there a way to create a generic that prevents circular variables?
This should work regardless of depth or circular reference type, not just for T itself...

So far I got this:

export type IsEqual&lt;A, B&gt; =
    (&lt;G&gt;() =&gt; G extends A ? 1 : 2) extends
    (&lt;G&gt;() =&gt; G extends B ? 1 : 2)
    ? true
    : false;

    
type DisallowCircular&lt;T&gt; = {
    [K in keyof T]: true extends IsEqual&lt;T[K], T&gt; ? never : T[K]
};

function noCircularAllowed&lt;T extends DisallowCircular&lt;T&gt;&gt;(a: T) {

}

class Foo {
    abc: string;
    circular: Foo;

    constructor() {
        this.abc = &quot;Hello&quot;;
        this.circular = this;
    }
}

const foo = new Foo()

noCircularAllowed(foo)

Which successfully disallows foo as an input as it has a circular dependency to itself.

Edit 2:
I see that my question was a bit confusing, changed it for clarity, not just assignments, also prevent passing it to a function etc.

Edit 3:
Jcalz correctly stated that this will also catch recursive values and not just self references, which isn't the desired behavior, now that I understand my mistake I realized why this is currently impossible.

答案1

得分: 2

不,这是不可能的。TypeScript具有结构类型系统,它无法表示对象身份或了解循环引用。但是,如果您不使用any,而是正确为对象的所有属性添加类型,那么至少会更难意外地发生这种情况。

英文:

No, this is not possible. TypeScript has a structural typesystem, it cannot express object identity or know about circular references.
However, if you don't use any but properly type all the properties of your object, it will at least make it harder to do so accidentally.

huangapple
  • 本文由 发表于 2023年2月9日 00:34:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75388890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定