Skip to content

Commit e120e57

Browse files
biniona-mongodbnbbeekenterakilobytedariakpjason-price-mongodb
authored
(DOCSP-17935) Fundamentals > TypeScript (#247)
Co-authored-by: Neal Beeken <nbbeeken@users.noreply.github.com> Co-authored-by: Nathan <nathan.leniz@mongodb.com> Co-authored-by: Daria Pardue <81593090+dariakp@users.noreply.github.com> Co-authored-by: Jason Price <jason-price-mongodb@users.noreply.github.com>
1 parent 931b485 commit e120e57

File tree

8 files changed

+220
-0
lines changed

8 files changed

+220
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// start-no-error
2+
interface TestType {
3+
field: { nested: number };
4+
}
5+
const database = client.db("<your db>");
6+
const collection = database.collection<TestType>("<your collection>");
7+
await collection.updateOne({}, { $set: { "field.nested": "A string" } });
8+
// end-no-error
9+
// start-error
10+
interface TestType {
11+
field: { nested: number };
12+
}
13+
const database = client.db("<your db>");
14+
const collection = database.collection<TestType>("<your collection>");
15+
await collection.updateOne({}, { $set: { field: { nested: "A string" } } });
16+
// end-error
17+
// start-no-key
18+
interface TestNumber {
19+
myNumber: number;
20+
}
21+
22+
const database = client.db("<your db>");
23+
const collection = db.collection<TestNumber>("...");
24+
collection.find({ someRandomKey: "Accepts any type!" });
25+
// end-no-key
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
interface Pet {
2+
name: string;
3+
age: number;
4+
cute: true;
5+
}
6+
7+
const database = client.db("<your database>");
8+
const collection = database.collection<Pet>("<your collection>");
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// start-no-doc
2+
// returns no documents
3+
collection.find({ field: { s1: "hi" } });
4+
// end-no-doc
5+
// start-doc
6+
// returns your document (uses dot notation)
7+
collection.find({ "field.s1": "hi" });
8+
9+
// returns your document (does not use dot notation)
10+
collection.find({
11+
$jsonSchema: {
12+
required: ["field"],
13+
properties: {
14+
field: { bsonType: "object", properties: { s1: { enum: ["hi"] } } },
15+
},
16+
},
17+
});
18+
// end-doc

source/fundamentals.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Fundamentals
1717
/fundamentals/logging
1818
/fundamentals/monitoring
1919
/fundamentals/gridfs
20+
/fundamentals/typescript
2021

2122
The **Fundamentals** section contains detailed information to help you
2223
expand your knowledge on how to use MongoDB with the Node.js driver. The

source/fundamentals/typescript.txt

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
==========
2+
TypeScript
3+
==========
4+
5+
.. default-domain:: mongodb
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 2
11+
:class: singlecols
12+
13+
Overview
14+
--------
15+
16+
In this guide, you can learn about the **TypeScript** features and limitations
17+
of the MongoDB Node.js driver. TypeScript is a strongly typed programming
18+
language that compiles to JavaScript.
19+
20+
All TypeScript features of the driver are optional. All valid JavaScript
21+
code written with the driver is also valid TypeScript code.
22+
23+
For more information, see the
24+
`TypeScript website <https://www.typescriptlang.org/>`__.
25+
26+
Features
27+
--------
28+
29+
If you use TypeScript, you can specify a type for some classes in the driver.
30+
All classes that accept a type parameter in the driver have the default type
31+
``Document``. The ``Document`` interface has the following definition:
32+
33+
.. code-block:: typescript
34+
35+
interface Document {
36+
[key: string]: any;
37+
}
38+
39+
Any object type can extend the ``Document`` interface.
40+
41+
For more information on object types, see the
42+
`TypeScript handbook <https://www.typescriptlang.org/docs/handbook/2/objects.html>`__.
43+
44+
Extend Document
45+
~~~~~~~~~~~~~~~
46+
47+
The following classes accept any type that extends the ``Document``
48+
interface:
49+
50+
- :node-api-4.0:`Collection <classes/collection.html>`
51+
- :node-api-4.0:`ChangeStream <classes/changestream.html>`
52+
53+
You can pass a type parameter that extends the ``Document`` interface like this:
54+
55+
.. literalinclude:: /code-snippets/typescript/extend-document.ts
56+
:language: typescript
57+
:linenos:
58+
59+
.. important:: Keys Not in Type Parameter Receive ``any`` Type
60+
61+
Keys not listed in your specified type parameter receive the ``any`` type.
62+
The following code snippet demonstrates this behavior:
63+
64+
.. literalinclude:: /code-snippets/typescript/dot-notation.ts
65+
:language: typescript
66+
:linenos:
67+
:start-after: start-no-key
68+
:end-before: end-no-key
69+
70+
Any Type
71+
~~~~~~~~
72+
73+
The following classes accept any type parameter:
74+
75+
- :node-api-4.0:`FindCursor <classes/findcursor.html>`
76+
- :node-api-4.0:`AggregationCursor <classes/aggregationcursor.html>`
77+
78+
You can find a code snippet that shows how to specify a type for the ``FindCursor``
79+
class in the
80+
:ref:`Find Multiple Documents Usage Example <node-driver-find-usage-example-code-snippet>`.
81+
82+
Limitations
83+
-----------
84+
85+
.. _node-driver-typescript-limitations-dot-notation:
86+
87+
The driver cannot infer the type of values with keys containing **dot
88+
notation**. Dot notation is a property access syntax for navigating BSON objects.
89+
Click on the tabs to see code snippets that highlight this behavior:
90+
91+
.. tabs::
92+
93+
.. tab:: Dot Notation
94+
:tabid: dot-notation
95+
96+
The following code snippet does not raise a type error:
97+
98+
.. literalinclude:: /code-snippets/typescript/dot-notation.ts
99+
:language: typescript
100+
:linenos:
101+
:start-after: start-no-error
102+
:end-before: end-no-error
103+
104+
.. tab:: Nested Objects
105+
:tabid: nested-objects
106+
107+
The following code snippet raises a type error:
108+
109+
.. literalinclude:: /code-snippets/typescript/dot-notation.ts
110+
:language: typescript
111+
:linenos:
112+
:start-after: start-error
113+
:end-before: end-error
114+
115+
This is the error:
116+
117+
.. code-block:: text
118+
119+
Type 'string' is not assignable to type 'number'.
120+
121+
Despite the lack of type safety, we still recommend that you use dot notation to
122+
access nested fields in query and update documents when you use TypeScript. You
123+
must manually check that your nested field values have your intended type.
124+
125+
.. note:: Reason To Use Dot Notation
126+
127+
In the MongoDB Query Language, you must match a subdocument exactly
128+
when specifying subdocuments in a query. Dot notation allows you to query
129+
nested fields without matching subdocuments exactly.
130+
131+
To show this behavior, lets say you have a collection containing
132+
only the following document:
133+
134+
.. code-block:: json
135+
136+
{ field: { s1: "hi", s2: "bye" } }
137+
138+
The following query returns no results from this collection, as the value of
139+
``field`` does not exactly match ``{ s1: "hi" }``:
140+
141+
.. literalinclude:: /code-snippets/typescript/note-on-dot-notation.ts
142+
:language: typescript
143+
:linenos:
144+
:start-after: start-no-doc
145+
:end-before: end-no-doc
146+
147+
The following queries both return your document:
148+
149+
.. literalinclude:: /code-snippets/typescript/note-on-dot-notation.ts
150+
:language: typescript
151+
:linenos:
152+
:start-after: start-doc
153+
:end-before: end-doc
154+
155+
The syntax of the query that does not use dot notation is cumbersome and hard
156+
to understand, and may not be worth the type safety obtained from
157+
avoiding dot notation.
158+
159+
For more information on dot notation, see :manual:`the MongoDB Manual </core/document/#dot-notation>`.

source/usage-examples/bulkWrite.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ to ``bulkWrite()`` includes examples of ``insertOne``, ``updateMany``, and
8787
:language: typescript
8888
:linenos:
8989

90+
.. important:: Dot Notation Loses Type Safety
91+
92+
You lose type-safety for values when you use dot notation in keys. For
93+
more information, see our guide on
94+
:ref:`TypeScript in the driver <node-driver-typescript-limitations-dot-notation>`.
95+
9096
When you run the code sample, your output should resemble the following:
9197

9298
.. code-block:: javascript

source/usage-examples/find.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ uses the following parameters:
5050

5151
.. include:: /includes/connect-guide-note.rst
5252

53+
.. _node-driver-find-usage-example-code-snippet:
5354

5455
.. tabs::
5556

source/usage-examples/findOne.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ collection. It uses the following parameters:
4848

4949
.. include:: /includes/connect-guide-note.rst
5050

51+
.. _node-driver-findone-usage-example-code-snippet:
52+
5153
.. tabs::
5254

5355
.. tab:: JavaScript

0 commit comments

Comments
 (0)