From cf3a3bb0bd8d6c638c1ff4ab883eaf1cd4b223ee Mon Sep 17 00:00:00 2001 From: Luke Abby Date: Sat, 19 Oct 2024 16:38:46 -0700 Subject: [PATCH] Fix "Type of property circularly references itself in mapped type" errors --- .../client/data/abstract/client-document.d.mts | 16 +++++++++++++--- src/foundry/common/abstract/document.d.mts | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/foundry/client/data/abstract/client-document.d.mts b/src/foundry/client/data/abstract/client-document.d.mts index 0d5311a0f..b5b47351c 100644 --- a/src/foundry/client/data/abstract/client-document.d.mts +++ b/src/foundry/client/data/abstract/client-document.d.mts @@ -554,11 +554,14 @@ declare global { * A mixin which extends each Document definition with specialized client-side behaviors. * This mixin defines the client-side interface for database operations and common document behaviors. */ - // Note: Unlike most mixins, `ClientDocumentMixin` actually requires a specific constructor, the same as `Document`. - // This means that `BaseClass extends Document.AnyConstructor` would be too permissive. + // FIXME(LukeAbby): Unlike most mixins, `ClientDocumentMixin` actually requires a specific constructor, the same as `Document`. + // This means that `BaseClass extends Document.Internal.Constructor` is actually too permissive. + // However this easily leads to circularities. + // + // Note(LukeAbby): The seemingly redundant merging in of `AnyDocument` makes it easier for tsc to recognize that anything extending `ClientDocumentMixin` is also a document. function ClientDocumentMixin( Base: BaseClass, - ): Mixin>, BaseClass>; + ): AnyDocument & Mixin>, BaseClass>; namespace ClientDocument { interface SortOptions extends SortingHelpers.SortOptions { @@ -645,6 +648,13 @@ declare namespace DropData { } } +// This is yet another `AnyDocument` type. +// It exists specifically because the `Document.AnyConstructor` type is too safe to be merged in with a mixin. +// The `arg0: never, ...args: never[]` trick trips up the base constructor check and so this one with an actual `...args: any[]` one is used instead. +declare class AnyDocument extends Document { + constructor(...args: any[]); +} + type InternalData = DropData.Data>; interface FromDropDataOptions { diff --git a/src/foundry/common/abstract/document.d.mts b/src/foundry/common/abstract/document.d.mts index b07505aa7..501204b12 100644 --- a/src/foundry/common/abstract/document.d.mts +++ b/src/foundry/common/abstract/document.d.mts @@ -882,7 +882,7 @@ declare namespace Document { type ConfiguredClass = ConfiguredClassForName; - type ConfiguredClassForName = ConfiguredDocuments[Name]; + type ConfiguredClassForName = MakeConform; type SubTypesOf = ConfiguredInstanceForName extends { type: infer Types } ? Types : typeof foundry.CONST.BASE_DOCUMENT_TYPE;