Skip to content

Commit 44a2176

Browse files
ajhuh-mdbmongoKartnbbeeken
authored andcommitted
DOCSP-25723 Updates to Mutually Recursive Schema Types (#459)
* DOCSP-25723 Updates to Mutually Recursive Schema Types * edit mutually recursive pet code block * edit collection schema name * more specific limitations menu text * MW comment edits * rephrase confusing sentence * remove warning notes for v4.3-4.10 behavior * Apply suggestions from code review Co-authored-by: Neal Beeken <[email protected]> Co-authored-by: Mike Woofter <[email protected]> Co-authored-by: Neal Beeken <[email protected]> (cherry picked from commit 72be9c1)
1 parent a73d906 commit 44a2176

File tree

3 files changed

+61
-56
lines changed

3 files changed

+61
-56
lines changed

source/fundamentals/typescript.txt

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ For more information on object types, see the
4444
Type Parameters that Extend Document
4545
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4646

47-
The following classes accept all types that both extend
48-
the ``Document`` interface and are not mutually recursive:
47+
The following classes accept all types that extend the ``Document`` interface:
4948

5049
.. _node-mongodb-type-parameters-extend-document:
5150

@@ -71,14 +70,10 @@ You can pass a type parameter that extends the ``Document`` interface like this:
7170
:start-after: start-no-key
7271
:end-before: end-no-key
7372

74-
To view an example of a mutually recursive type, which is not supported by the
75-
:ref:`preceding classes <node-mongodb-type-parameters-extend-document>`,
76-
see the :ref:`<node-driver-limitations-mutual-recursion>` section.
77-
7873
Type Parameters of Any Type
7974
~~~~~~~~~~~~~~~~~~~~~~~~~~~
8075

81-
The following classes accept all type parameters that are not mutually recursive:
76+
The following classes accept all type parameters:
8277

8378
.. _node-mongodb-type-parameters-any-type:
8479

@@ -89,10 +84,6 @@ You can find a code snippet that shows how to specify a type for the ``FindCurso
8984
class in the
9085
:ref:`Find Multiple Documents Usage Example <node-driver-find-usage-example-code-snippet>`.
9186

92-
To view an example of a mutually recursive type, which is not supported by the
93-
:ref:`preceding classes <node-mongodb-type-parameters-any-type>`,
94-
see the :ref:`<node-driver-limitations-mutual-recursion>` section.
95-
9687

9788
Type Safety and Dot Notation
9889
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

source/includes/limitations/limits.rst

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
Learn about the following TypeScript specific limitations of the {+driver-short+}:
22

33
- :ref:`No type safety for dot notation references to nested instances of recursive types <node-driver-recursive-types-dot-notation>`
4-
- :ref:`No mutually recursive types <node-driver-limitations-mutual-recursion>`
4+
- :ref:`Depth limitations on type safety for mutually recursive types <node-driver-limitations-mutual-recursion>`
55

66
.. _node-driver-recursive-types-dot-notation:
77

88
Recursive Types and Dot Notation
99
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1010

11-
.. important:: Impacted Versions
12-
13-
- 4.3
14-
- 4.4
15-
16-
The {+driver-short+} cannot provide type safety within nested instances of
11+
The {+driver-short+} cannot provide type safety within nested instances of
1712
**recursive types** referenced through dot notation.
1813

1914
A recursive type is a type that references itself. You can update
@@ -80,40 +75,54 @@ in the MongoDB manual.
8075
Mutual Recursion
8176
~~~~~~~~~~~~~~~~
8277

83-
.. important:: Impacted Versions
84-
85-
- 4.3
86-
- 4.4
87-
88-
You cannot specify a **mutually recursive** type as a type parameter.
89-
90-
A mutually recursive type exists when two types contain a property that is of
91-
the other's type. You can update the
92-
:ref:`Pet <mongodb-node-typescript-pet-interface>` interface
93-
to be mutually recursive by allowing a pet to have a handler, and defining a
94-
handler to have a pet. The following are the mutually
78+
A **mutually recursive** type exists when two types contain a property that is of
79+
the other's type. You can update the :ref:`Pet <mongodb-node-typescript-pet-interface>`
80+
interface to be mutually recursive by allowing a pet to have a handler, and
81+
defining a handler to have a pet. The following examples reference the mutually
9582
recursive ``Pet`` and ``Handler`` interfaces:
9683

9784
.. code-block:: typescript
9885
:emphasize-lines: 2, 8
9986
100-
interface MutuallyRecursivePet {
87+
interface Pet {
10188
handler?: Handler;
10289
name: string;
10390
age: number;
10491
}
10592
10693
interface Handler {
107-
pet: MutuallyRecursivePet;
94+
pet: Pet;
10895
name: string;
10996
}
97+
98+
The {+driver-short+} provides type safety for mutually recursive types
99+
referenced through dot notation up to a depth of eight. The following code
100+
snippet assigns a ``string`` to a ``number`` and raises a type error because
101+
the referenced property is at a depth of four:
102+
103+
.. code-block:: typescript
104+
:emphasize-lines: 3
105+
106+
database
107+
.collection<Pet>("<your collection>")
108+
.findOne({'handler.pet.handler.pet.age': "four"});
110109
111-
If you specify a mutually recursive type, the TypeScript compiler raises the
112-
following error:
110+
The error raised by the preceding code snippet is as follows:
113111

114112
.. code-block:: none
115113
116-
error TS2615: Type of property 'r' circularly references itself in mapped type '{ [Key in keyof MutuallyRecursive]...
114+
index.ts(19,59): error TS2769: No overload matches this call.
115+
The last overload gave the following error.
116+
Type 'string' is not assignable to type 'Condition<number> | undefined'.
117+
118+
At a depth greater than or equal to eight, TypeScript compiles your code but no
119+
longer type checks it. The following code assigns a ``string`` to a ``number``
120+
property but does not cause a compilation error because the referenced property
121+
is at a depth of 10:
117122

118-
If you must apply a mutually recursive type to your classes, use version 4.2 of
119-
the {+driver-short+}.
123+
.. code-block:: typescript
124+
:emphasize-lines: 3
125+
126+
database
127+
.collection<Pet>("<your collection>")
128+
.findOne({'handler.pet.handler.pet.handler.pet.handler.pet.handler.pet.age': "four"});

source/whats-new.txt

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,46 +69,51 @@ To learn more, see the `v4.12.0 Release Highlights <https://github.com/mongodb/n
6969
What's New in 4.11
7070
------------------
7171

72-
The 4.11 {+driver-short+} release includes **recursive schema support**,
73-
meaning that you can use recursive types as the schema in the
74-
``Collection`` class. The driver also provides type safety for dot
75-
notation queries up to a depth of nine in this release. Typescript compiles
76-
your code beyond a depth of nine, but types fall back to ``any`` at
77-
this level. The recursive type depth limit is a current limitation in
78-
TypeScript.
72+
The 4.11 {+driver-short+} release includes added support for **mutually
73+
recursive** collection schema types. The driver also provides type safety for
74+
dot-notation queries up to a depth of eight in this release. At a depth greater
75+
than or equal to eight, Typescript successfully compiles your code but does not
76+
provide type safety. This depth limit on recursive types is a current limitation
77+
of TypeScript.
7978

80-
Recursive Schema Type Checking Example
81-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79+
Mutually Recursive Schema Type Checking Example
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8281

83-
Suppose we have a collection of type ``Collection<CircularSchema>``:
82+
Suppose we have a collection of type ``Collection<Author>`` that contains the
83+
following mutually recursive types:
8484

8585
.. code-block:: js
8686
:copyable: false
8787

88-
interface CircularSchema {
88+
interface Author {
8989
name: string;
90-
ref: CircularSchema;
90+
bestBook: Book;
9191
}
9292

93-
TypeScript enforces type checking below a depth of nine. The following
93+
interface Book {
94+
title: string;
95+
author: Author;
96+
}
97+
98+
TypeScript enforces type checking up to a depth of eight. The following
9499
code causes a TypeScript compilation error because the ``name`` property
95100
value must be a ``string`` type:
96101

97102
.. code-block:: js
98103
:copyable: false
99104

100-
collection.findOne({ 'ref.ref.ref.name': 25 })
105+
collection.findOne({ 'bestBook.author.bestBook.title': 25 })
101106

102-
At a depth greater than nine, TypeScript compiles your code but no
103-
longer type checks it. The following code assigns an ``int`` to a ``string``
104-
property but does not cause a compilation error because the
105-
referenced property is at a depth of 11:
107+
At a depth greater than or equal to eight, TypeScript compiles your code but no
108+
longer type checks it. For example, the following code assigns a ``number`` to a
109+
``string`` property but does not cause a compilation error because the
110+
referenced property is at a depth of 10:
106111

107112
.. code-block:: js
108113
:copyable: false
109114

110115
collection.findOne({
111-
'ref.ref.ref.ref.ref.ref.ref.ref.ref.ref.name': 25
116+
'bestBook.author.bestBook.author.bestBook.author.bestBook.author.bestBook.author.name': 25
112117
})
113118

114119
To learn more, see the `v4.11.0 Release Highlights <https://github.com/mongodb/node-mongodb-native/releases/tag/v4.11.0>`__.

0 commit comments

Comments
 (0)