-
Notifications
You must be signed in to change notification settings - Fork 51
(DOCSP-20071) Update TS Limitations #275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 29 commits
70649c4
fd76f80
438156c
42cae8c
fc3537b
1853bf5
ea95abc
b35c0d9
a758cdd
4ba4c20
47ec306
079cd5e
1be07ca
f61c9f1
7e36683
f2ec69e
eb77c53
2d3cc37
b48748e
e1648d0
ad6c58d
f45b0a8
fe64c9f
353416a
4bfa35e
f7967df
e3f65ec
8bd69e4
06de329
8fb218b
6276c5d
36730a5
67dc810
cc4fdb1
ad3b47e
59ed5e0
7a1748f
8c97f31
11ba220
5a41582
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
interface Pet { | ||
name: string; | ||
age: number; | ||
cute: true; | ||
} | ||
|
||
const database = client.db("<your database>"); | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,17 +41,19 @@ Any object type can extend the ``Document`` interface. | |
For more information on object types, see the | ||
`TypeScript handbook <https://www.typescriptlang.org/docs/handbook/2/objects.html>`__. | ||
|
||
Extend Document | ||
~~~~~~~~~~~~~~~ | ||
Type Parameters that Extend Document | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
The following classes accept any type that extends the ``Document`` | ||
interface: | ||
The following classes accept all types that both extend | ||
the ``Document`` interface and are not mutually recursive: | ||
|
||
- `Collection <{+api+}/classes/Collection.html>`__ | ||
- `ChangeStream <{+api+}/classes/ChangeStream.html>`__ | ||
|
||
You can pass a type parameter that extends the ``Document`` interface like this: | ||
|
||
.. _mongodb-node-typescript-pet-interface: | ||
|
||
.. literalinclude:: /code-snippets/typescript/extend-document.ts | ||
:language: typescript | ||
:linenos: | ||
|
@@ -67,10 +69,13 @@ You can pass a type parameter that extends the ``Document`` interface like this: | |
:start-after: start-no-key | ||
:end-before: end-no-key | ||
|
||
Any Type | ||
~~~~~~~~ | ||
To view an example of a mutually recursive type, which is not supported by the | ||
preceding classes, see the :ref:`<node-driver-limitations-mutual-recursion>` section. | ||
biniona-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Type Parameters of Any Type | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
The following classes accept any type parameter: | ||
The following classes accept all type parameters that are not mutually recursive: | ||
|
||
- `FindCursor <{+api+}/classes/FindCursor.html>`__ | ||
- `AggregationCursor <{+api+}/classes/AggregationCursor.html>`__ | ||
|
@@ -79,81 +84,119 @@ You can find a code snippet that shows how to specify a type for the ``FindCurso | |
class in the | ||
:ref:`Find Multiple Documents Usage Example <node-driver-find-usage-example-code-snippet>`. | ||
|
||
Limitations | ||
----------- | ||
To view an example of a mutually recursive type, which is not supported by the | ||
preceding classes, see the :ref:`<node-driver-limitations-mutual-recursion>` section. | ||
|
||
.. _node-driver-typescript-limitations-dot-notation: | ||
.. _node-driver-limitations: | ||
|
||
The driver cannot infer the type of values with keys containing **dot | ||
notation**. Dot notation is a property access syntax for navigating BSON objects. | ||
Click on the tabs to see code snippets that highlight this behavior: | ||
Limitations For Driver Version {+version+} | ||
ccho-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
biniona-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
---------------------------------- | ||
|
||
.. tabs:: | ||
The following subsections describe the TypeScript specific limitations of | ||
biniona-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
version {+version+} of the {+driver-long+}. | ||
|
||
.. tab:: Dot Notation | ||
:tabid: dot-notation | ||
Many limitations of the {+driver-short+} relate to **recursive types**. | ||
ccho-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
A recursive type is a type that references itself. You can update | ||
the :ref:`Pet <mongodb-node-typescript-pet-interface>` interface | ||
to be recursive by allowing a pet to have its own pet. The following is the | ||
recursive ``Pet`` interface: | ||
|
||
The following code snippet does not raise a type error: | ||
.. _node-driver-limitations-recursive-pet: | ||
|
||
.. literalinclude:: /code-snippets/typescript/dot-notation.ts | ||
:language: typescript | ||
:linenos: | ||
:start-after: start-no-error | ||
:end-before: end-no-error | ||
.. code-block:: typescript | ||
:emphasize-lines: 2 | ||
|
||
.. tab:: Nested Objects | ||
:tabid: nested-objects | ||
interface RecursivePet { | ||
pet?: RecursivePet; | ||
name: string; | ||
age: number; | ||
} | ||
|
||
The following code snippet raises a type error: | ||
Recursive Types and Dot Notation | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
.. literalinclude:: /code-snippets/typescript/dot-notation.ts | ||
:language: typescript | ||
:linenos: | ||
:start-after: start-error | ||
:end-before: end-error | ||
The {+driver-short+} cannot provide type safety within nested instances of | ||
recursive types referenced through **dot notation**. Dot notation is a property | ||
access syntax for navigating BSON objects. | ||
ccho-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
This is the error: | ||
For example, the following code snippet references a nested instance of the | ||
biniona-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
:ref:`RecursivePet <node-driver-limitations-recursive-pet>` interface | ||
with an incorrect type using dot notation, but the TypeScript compiler | ||
does not raise an error: | ||
biniona-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
.. code-block:: text | ||
.. code-block:: typescript | ||
:emphasize-lines: 3 | ||
|
||
Type 'string' is not assignable to type 'number'. | ||
database | ||
.collection<RecursivePet>("your-collection") | ||
biniona-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.findOne({ "pet.age": "Spot" }); | ||
|
||
Despite the lack of type safety, we still recommend that you use dot notation to | ||
access nested fields in query and update documents when you use TypeScript. You | ||
must manually check that your nested field values have your intended type. | ||
The following code snippet references a top-level instance of the | ||
``RecursivePet`` interface with an incorrect type and raises a type error: | ||
|
||
.. note:: Reason To Use Dot Notation | ||
.. tabs:: | ||
ccho-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
In the MongoDB Query Language, you must match a subdocument exactly | ||
when specifying subdocuments in a query. Dot notation allows you to query | ||
nested fields without matching subdocuments exactly. | ||
.. tab:: Code Snippet | ||
:tabid: code-snippet | ||
|
||
To show this behavior, lets say you have a collection containing | ||
only the following document: | ||
.. code-block:: typescript | ||
:emphasize-lines: 3 | ||
|
||
.. code-block:: json | ||
database | ||
.collection<RecursivePet>("your-collection") | ||
.findOne({ pet: "Spot" }); | ||
|
||
{ field: { s1: "hi", s2: "bye" } } | ||
.. tab:: Error | ||
:tabid: error | ||
|
||
The following query returns no results from this collection, as the value of | ||
``field`` does not exactly match ``{ s1: "hi" }``: | ||
.. code-block:: text | ||
|
||
index.ts(19,59): error TS2769: No overload matches this call. | ||
The last overload gave the following error. | ||
Type 'string' is not assignable to type 'Condition<Pet>'. | ||
|
||
.. literalinclude:: /code-snippets/typescript/note-on-dot-notation.ts | ||
:language: typescript | ||
:linenos: | ||
:start-after: start-no-doc | ||
:end-before: end-no-doc | ||
If you must have type safety within nested instances of recursive types, | ||
you must write your query or update without dot notation. | ||
biniona-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The following queries both return your document: | ||
To learn more about dot notation, see | ||
:manual:`Dot Notation </core/document/#dot-notation>` | ||
in the MongoDB manual. | ||
|
||
.. literalinclude:: /code-snippets/typescript/note-on-dot-notation.ts | ||
:language: typescript | ||
:linenos: | ||
:start-after: start-doc | ||
:end-before: end-doc | ||
.. _node-driver-limitations-mutual-recursion: | ||
|
||
The syntax of the query that does not use dot notation is cumbersome and hard | ||
to understand, and may not be worth the type safety obtained from | ||
avoiding dot notation. | ||
Mutual Recursion | ||
~~~~~~~~~~~~~~~~ | ||
|
||
You cannot specify a mutually recursive type as a type parameter in version | ||
{+version+} of the driver. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this apply to all versions of the driver? If not, here's how I might structure this to prevent errors:
This may become increasingly valuable when we need to apply changes to multiple driver versions of this page in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Applies to all instances. |
||
|
||
If you specify a mutually recursive type, the TypeScript compiler raises the | ||
following error: | ||
|
||
.. code-block:: text | ||
|
||
error TS2615: Type of property 'r' circularly references itself in mapped type '{ [Key in keyof MutuallyRecursive]: MutuallyRecursive[Key] extends MutuallyRecursive ? [Key] : MutuallyRecursive extends MutuallyRecursive[Key] ? [...] : MutuallyRecursive[Key] extends readonly (infer ArrayType)[] ? MutuallyRecursive extends ArrayType ? [...] : ArrayType extends MutuallyRecursive ? [...] : [...] : [...'. | ||
ccho-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
A mutually recursive type exists when two types define themselves relative | ||
to each other. You can update the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed a comment because of my own misunderstanding. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what "property type" is referring to in the preceding comment. I think the following sentence is the intended suggestion: "A mutually recursive type exists when two types contain a property that is of the other's type". I'll update "relative to each other" to the preceding sentence, as I agree it is more precise. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for clarification, I used "property type", which seems consistent with TypeScript nomenclature according to their documentation. An example of a property type of a Type in your MutuallyRecursivePet interface is "string" for (name) or "number" (for age). Let me know if my terminology is incorrect and what the appropriate term is if so. "Type" is unfortunately and maybe unavoidably ambiguous in the sentence, so I omitted it explicitly in my suggestion. |
||
:ref:`Pet <mongodb-node-typescript-pet-interface>` interface | ||
to be mutually recursive by allowing a pet to have a handler, and defining a | ||
handler to have a pet. The following is the mutually | ||
recursive ``Pet`` interface: | ||
|
||
.. code-block:: typescript | ||
:emphasize-lines: 2, 8 | ||
|
||
interface MutuallyRecursivePet { | ||
handler?: Handler; | ||
name: string; | ||
age: number; | ||
} | ||
|
||
interface Handler { | ||
pet: MutuallyRecursivePet; | ||
name: string; | ||
} | ||
|
||
For more information on dot notation, see :manual:`the MongoDB Manual </core/document/#dot-notation>`. | ||
If you must apply a mutually recursive type to your classes, use version 4.2 of | ||
the {+driver-long+}. | ||
ccho-mongodb marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.