Is there a method to create a general solution that can prevent circular variables in JavaScript? This solution should be effective for any level of depth or type of circular reference, not limited to the variable itself...
So far I've come up with the following approach:
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)
This successfully prevents using 'foo' as an input due to its circular dependency on itself.
Edit 2: I realize my initial question may have been unclear, I have revised it for better clarity - not just handling assignments but also preventing passing circular values to functions and other scenarios.
Edit 3: As pointed out by Jcalz, the current implementation captures recursive values as well which was unintended. After understanding my mistake, I now see why achieving the desired behavior is currently challenging.