Circular reference with keyof and never

I’m having trouble understanding some typescript behavior in regards to circular references for types.

type NonEmptyObject<T> = keyof T extends never ? never : T

type Base = { [key: PropertyKey]: Nested }; // I'm using this instead of Record to avoid a circular reference.
type NonEmptyBase = NonEmptyObject<Base>;
type Nested = string | NonEmptyBase;

Type alias 'NonEmptyBase' circularly references itself.ts(2456)

Type alias 'Nested' circularly references itself.ts(2456)

If I switch to generics, everything works fine. But this looks wrong and feels even more circularly mixed up.

type Base<T extends Base<T>> = { [key: PropertyKey]: Nested<T> };
type NonEmptyBase<T extends Base<T>> = NonEmptyObject<T>;
type Nested<T extends Base<T>> = string | NonEmptyBase<T>;

Why is this and how can I achieve the desired outcome without generics?

  • would type Nested = string | Base be okay for you? Or do you necessarily need the nested ones nonempty? I’m really unsure about your NonEmptyBase. Your generic doesn’t make any sense in here, since you are not passing any generic types there, but rather a Base, which’s key are PropertyKey, so basically NonEmptyBase is the same as Base

    – 

  • I do need the Base to be nonempty. The reasoning is that I don’t want to be able to pass an empty object into the function using this type. I have tried extending the generic to NonEmptyObject<T extends object>, but unfortunately that didn’t change anything.

    – 

The error you’re encountering is due to circular references in your type definitions. TypeScript is unable to resolve these circular references when defining type aliases directly.

In your initial code, the NonEmptyBase type refers to NonEmptyObject, and Base refers to Nested, while Nested also refers to NonEmptyBase. This circular reference creates an error.

To achieve the desired outcome without using generics, you can use interfaces instead of type aliases.

As per this link – [1]: https://github.com/microsoft/TypeScript/issues/28748

Leave a Comment