Skip to content

Commit 8f01c2b

Browse files
authored
Merge pull request #4 from microsoft/v2
Pull across forks
2 parents cc8d5a1 + 17a55ec commit 8f01c2b

File tree

116 files changed

+1106
-421
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+1106
-421
lines changed

packages/documentation/copy/en/handbook-v2/Basics.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ The alternative is to use a _static_ type system to make predictions about what
6969

7070
## Static type-checking
7171

72-
Think back to that `TypeError` we got earlier from calling a `string`.
72+
Think back to that `TypeError` we got earlier from trying to call a `string` as a function.
7373
_Most people_ don't like to get any sorts of errors when running their code - those are considered bugs!
7474
And when we write new code, we try our best to avoid introducing new bugs.
7575

@@ -163,8 +163,6 @@ if (value !== "a") {
163163

164164
## Types for Tooling
165165

166-
<!-- TODO: this section's title sucks -->
167-
168166
TypeScript can catch bugs when we make mistakes in our code.
169167
That's great, but TypeScript can _also_ prevent us from making those mistakes in the first place.
170168

@@ -174,14 +172,25 @@ Once it has that information, it can also start _suggesting_ which properties yo
174172
That means TypeScript can be leveraged for editing code too, and the core type-checker can provide error messages and code completion as you type in the editor.
175173
That's part of what people often refer to when they talk about tooling in TypeScript.
176174

177-
<!-- TODO: insert GIF of completions here -->
175+
<!-- prettier-ignore -->
176+
```ts twoslash
177+
// @noErrors
178+
// @esModuleInterop
179+
import express from "express";
180+
const app = express();
181+
182+
app.get("/", function (req, res) {
183+
res.sen
184+
// ^|
185+
});
186+
187+
app.listen(3000);
188+
```
178189

179190
TypeScript takes tooling seriously, and that goes beyond completions and errors as you type.
180191
An editor that supports TypeScript can deliver "quick fixes" to automatically fix errors, refactorings to easily re-organize code, and useful navigation features for jumping to definitions of a variable, or finding all references to a given variable.
181192
All of this is built on top of the type-checker and fully cross-platform, so it's likely that [your favorite editor has TypeScript support available](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support).
182193

183-
<!-- TODO: validate that link -->
184-
185194
## `tsc`, the TypeScript compiler
186195

187196
We've been talking about type-checking, but we haven't yet used our type-_checker_.

packages/documentation/copy/en/handbook-v2/Everyday Types.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ As we learn about the types themselves, we'll also learn about the places where
1717
We'll start by reviewing the most basic and common types you might encounter when writing JavaScript or TypeScript code.
1818
These will later form the core "building blocks" of more complex types.
1919

20-
## Primitives `string`, `number`, and `boolean`
20+
## The primitives: `string`, `number`, and `boolean`
2121

22-
JavaScript has three main [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) kinds of values: `string`, `number`, and `boolean`.
22+
JavaScript has three very commonly used [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) kinds of values: `string`, `number`, and `boolean`.
2323
Each has a corresponding type in TypeScript.
2424
As you might expect, these are the same names you'd see if you used the JavaScript `typeof` operator on a value of those types:
2525

@@ -367,7 +367,7 @@ Here are the most relevant differences between the two that you should be aware
367367
You'll learn more about these concepts in later chapters, so don't worry if you don't understand all of these right away.
368368

369369
- Type aliases may not participate [in declaration merging, but interfaces can](/play?#code/PTAEEEDtQS0gXApgJwGYEMDGjSfdAIx2UQFoB7AB0UkQBMAoEUfO0Wgd1ADd0AbAK6IAzizp16ALgYM4SNFhwBZdAFtV-UAG8GoPaADmNAcMmhh8ZHAMMAvjLkoM2UCvWad+0ARL0A-GYWVpA29gyY5JAWLJAwGnxmbvGgALzauvpGkCZmAEQAjABMAMwALLkANBl6zABi6DB8okR4Jjg+iPSgABboovDk3jjo5pbW1d6+dGb5djLwAJ7UoABKiJTwjThpnpnGpqPBoTLMAJrkArj4kOTwYmycPOhW6AR8IrDQ8N04wmo4HHQCwYi2Waw2W1S6S8HX8gTGITsQA).
370-
- Interfaces may only be used to [declare object types, not primitives](/play?#code/PTAEAkFMCdIcgM6gC4HcD2pIA8CGBbABwBtIl0AzUAKBFAFcEBLAOwHMUBPQs0XFgCahWyGBVwBjMrTDJMAshOhMARpD4tQ6FQCtIE5DWoixk9QEEWAeV37kARlABvaqDegAbrmL1IALlAEZGV2agBfampkbgtrWwMAJlAAXmdXdy8ff0Dg1jZwyLoAVWZ2Lh5QVHUJflAlSFxROsY5fFAWAmk6CnRoLGwmILzQQmV8JmQmDzI-SOiKgGV+CaYAL0gBBdyy1KCQ-Pn1AFFplgA5enw1PtSWS+vCsAAVAAtB4QQWOEMKBuYVUiVCYvYQsUTQcRSBDGMGmKSgAAa-VEgiQe2GLgKQA).
370+
- Interfaces may only be used to [declare the shapes of object, not re-name primitives](/play?#code/PTAEAkFMCdIcgM6gC4HcD2pIA8CGBbABwBtIl0AzUAKBFAFcEBLAOwHMUBPQs0XFgCahWyGBVwBjMrTDJMAshOhMARpD4tQ6FQCtIE5DWoixk9QEEWAeV37kARlABvaqDegAbrmL1IALlAEZGV2agBfampkbgtrWwMAJlAAXmdXdy8ff0Dg1jZwyLoAVWZ2Lh5QVHUJflAlSFxROsY5fFAWAmk6CnRoLGwmILzQQmV8JmQmDzI-SOiKgGV+CaYAL0gBBdyy1KCQ-Pn1AFFplgA5enw1PtSWS+vCsAAVAAtB4QQWOEMKBuYVUiVCYvYQsUTQcRSBDGMGmKSgAAa-VEgiQe2GLgKQA).
371371
- Interface names will [_always_ appear in their original form](/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWY2Q-YAjABMAMwALA+gbsVjNXW8yxySoAADaAA0CCaZbPh1XYqXgOIY0ZgmcK0AA0nyaLFhhGY8F4AHJmEJILCWsgZId4NNfIgGFdcIcUTVfgBlZTOWC8T7kAJ42G4eT+GS42QyRaYbCgXAEEguTzeXyCjDBSAAQSE8Ai0Xsl0K9kcziExDeiQs1lAqSE6SyOTy0AKQ2KHk4p1V6s1OuuoHuzwArMagA) in error messages, but _only_ when they are used by name.
372372
- Type alias names [_may_ appear in error messages](/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWZWhfYAjABMAMwALA+gbsVjoADqgjKESytQPxCHghAByXigYgBfr8LAsYj8aQMUASbDQcRSExCeCwFiIQh+AKfAYyBiQFgOPyIaikSGLQo0Zj-aazaY+dSaXjLDgAGXgAC9CKhDqAALxJaw2Ib2RzOISuDycLw+ImBYKQflCkWRRD2LXCw6JCxS1JCdJZHJ5RAFIbFJU8ADKC3WzEcnVZaGYE1ABpFnFOmsFhsil2uoHuzwArO9SmAAEIsSFrZB-GgAjjA5gtVN8VCEc1o1C4Q4AGlR2AwO1EsBQoAAbvB-gJ4HhPgB5aDwem-Ph1TCV3AEEirTp4ELtRbTPD4vwKjOfAuioSQHuDXBcnmgACC+eCONFEs73YAPGGZVT5cRyyhiHh7AAON7lsG3vBggB8XGV3l8-nVISOgghxoLq9i7io-AHsayRWGaFrlFauq2rg9qaIGQHwCBqChtKdgRo8TxRjeyB3o+7xAA), sometimes in place of the equivalent anonymous type (which may or may not be desirable).
373373

@@ -516,7 +516,7 @@ The second change means "I know for other reasons that `req.method` has the valu
516516

517517
## `null` and `undefined`
518518

519-
JavaScript has two primitive values, `null` and `undefined`, both of which are used to signal absent or uninitialized values.
519+
JavaScript has two primitive values used to signal absent or uninitialized value: `null` and `undefined`.
520520

521521
TypeScript has two corresponding _types_ by the same names. How these types behave depends on whether you have the `strictNullChecks` option on.
522522

@@ -554,3 +554,38 @@ function liveDangerously(x?: number | null) {
554554
```
555555

556556
Just like other type assertions, this doesn't change the runtime behavior of your code, so it's important to only use `!` when you know that the value _can't_ be `null` or `undefined`.
557+
558+
### Less Common Primitives
559+
560+
It's worth mentioning the rest of the primitives in JavaScript which are represented in the type system.
561+
Though we will not go into depth here.
562+
563+
##### `bigint`
564+
565+
There is a primitive in JavaScript used for very large integers, `BitInt`:
566+
567+
```ts
568+
// Creating a bigint via the BigInt function
569+
let foo: bigint = BigInt(100);
570+
571+
// Creating a BigInt via the literal syntax
572+
let bar: bigint = 100n;
573+
```
574+
575+
You can learn more about BitInt in [the TypeScript 3.2 release notes](/docs/handbook/release-notes/typescript-3-2.html#bigint).
576+
577+
##### `symbol`
578+
579+
There is a primitive in JavaScript used to create a globally unique reference via the function `Symbol()`:
580+
581+
```ts twoslash
582+
// @errors: 2367
583+
const firstName = Symbol("name");
584+
const secondName = Symbol("name");
585+
586+
if (firstName === secondName) {
587+
// Can't ever happen
588+
}
589+
```
590+
591+
You can learn more about them in [Symbols handbook reference page](/docs/handbook/symbols.html).

packages/documentation/copy/en/handbook-v2/More on Functions.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,3 +726,73 @@ function sum({ a, b, c }: ABC) {
726726
```
727727

728728
## Assignability of Functions
729+
730+
### Return type `void`
731+
732+
The `void` return type for functions can produce some unusual, but expected behavior.
733+
734+
Contextual typing with a return type of `void` does **not** force functions to **not** return something. Another way to say this is a contextual function type with a `void` return type (`type vf = () => void`), when implemented, can return _any_ other value, but it will be ignored.
735+
736+
Thus, the following implementations of the type `() => void` are valid:
737+
```ts twoslash
738+
type voidFunc = () => void
739+
740+
const f1: voidFunc = () => {
741+
return true
742+
}
743+
744+
const f2: voidFunc = () => true
745+
746+
const f3: voidFunc = function () {
747+
return true
748+
}
749+
```
750+
751+
And when the return value of one of these functions is assigned to another variable, it will retain the type of `void`:
752+
753+
```ts twoslash
754+
type voidFunc = () => void
755+
756+
const f1: voidFunc = () => {
757+
return true
758+
}
759+
760+
const f2: voidFunc = () => true
761+
762+
const f3: voidFunc = function () {
763+
return true
764+
}
765+
// ---cut---
766+
const v1 = f1()
767+
768+
const v2 = f2()
769+
770+
const v3 = f3()
771+
```
772+
773+
This behavior exists so that the following code is valid even though `Array.prototype.push` returns a number and the `Array.prototype.forEach` method expects a function with a return type of `void`.
774+
```ts twoslash
775+
const src = [1, 2, 3]
776+
const dst = [0]
777+
778+
src.forEach(el => dst.push(el))
779+
```
780+
781+
There is one other special case to be aware of, when a literal function definition has a `void` return type, that function must **not** return anything.
782+
783+
```ts twoslash
784+
function f2 (): void {
785+
// @ts-expect-error
786+
return true
787+
}
788+
789+
const f3 = function (): void {
790+
// @ts-expect-error
791+
return true
792+
}
793+
```
794+
795+
For more on `void` please refer to these other documentation entries:
796+
- [v1 handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html#void)
797+
- [v2 handbook](https://www.typescriptlang.org/docs/handbook/2/functions.html#void)
798+
- [FAQ - "Why are functions returning non-void assignable to function returning void?"](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-functions-returning-non-void-assignable-to-function-returning-void)

packages/documentation/copy/en/handbook-v2/Narrowing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ function printAll(strs: string | string[] | null) {
240240
if (strs !== null) {
241241
if (typeof strs === "object") {
242242
for (const s of strs) {
243-
// ^?
243+
// ^?
244244
console.log(s);
245245
}
246246
} else if (typeof strs === "string") {

packages/documentation/copy/en/handbook-v2/Types from Transformation.md renamed to packages/documentation/copy/en/handbook-v2/Type Manipulation/Conditional Types.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
---
2-
title: Types from Transformation
2+
title: Conditional Types
33
layout: docs
4-
permalink: /docs/handbook/2/types-from-transformation.html
4+
permalink: /docs/handbook/2/conditional-types.html
55
oneline: "Step one in learning TypeScript: The basics types."
66
beta: true
77
---
88

9-
There are certain patterns that are very commonplace in JavaScript, like iterating over the keys of objects to create new ones, and returning different values based on the inputs given to us.
10-
This idea of creating new values and types on the fly is somewhat untraditional in typed languages, but TypeScript provides some useful base constructs in the type system to accurately model that behavior, much in the same way that `keyof` can be used to discuss the property names of objects, and indexed access types can be used to fetch values of a certain property name.
11-
12-
We'll quickly see that combined, these smaller constructs can be surprisingly powerful and can express many patterns in the JavaScript ecosystem.
13-
14-
## Conditional Types
15-
169
At the heart of most useful programs, we have to make decisions based on input.
1710
JavaScript programs are no different, but given the fact that values can be easily introspected, those decisions are also based on the types of the inputs.
1811
_Conditional types_ help describe the relation between the types of inputs and outputs.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: Indexed Access Types
3+
layout: docs
4+
permalink: /docs/handbook/2/indexed-access-types.html
5+
oneline: "Step one in learning TypeScript: The basics types."
6+
beta: true
7+
---
8+
9+
We can use an _indexed access type_ to look up a specific property on another type:
10+
11+
```ts twoslash
12+
type Person = { age: number; name: string; alive: boolean };
13+
type A = Person["age"];
14+
// ^?
15+
```
16+
17+
The indexing type is itself a type, so we can use unions, `keyof`, or other types entirely:
18+
19+
```ts twoslash
20+
type Person = { age: number; name: string; alive: boolean };
21+
// ---cut---
22+
type I1 = Person["age" | "name"];
23+
// ^?
24+
25+
type I2 = Person[keyof Person];
26+
// ^?
27+
28+
type AliveOrName = "alive" | "name";
29+
type I3 = Person[AliveOrName];
30+
// ^?
31+
```
32+
33+
You'll even see an error if you try to index a property that doesn't exist:
34+
35+
```ts twoslash
36+
// @errors: 2339
37+
type Person = { age: number; name: string; alive: boolean };
38+
// ---cut---
39+
type I1 = Person["alve"];
40+
```
41+
42+
Another example of indexing with an arbitrary type is using `number` to get the type of an array's elements.
43+
We can combine this with `typeof` to conveniently capture the element type of an array literal:
44+
45+
```ts twoslash
46+
const MyArray = [
47+
{ name: "Alice", age: 15 },
48+
{ name: "Bob", age: 23 },
49+
{ name: "Eve", age: 38 },
50+
];
51+
52+
type T = typeof MyArray[number];
53+
// ^?
54+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: Keyof Type Operator
3+
layout: docs
4+
permalink: /docs/handbook/2/indexed-access-types.html
5+
oneline: "Step one in learning TypeScript: The basics types."
6+
beta: true
7+
---
8+
9+
## The `keyof` type operator
10+
11+
The `keyof` operator takes an object type and produces a string or numeric literal union of its keys:
12+
13+
```ts twoslash
14+
type Point = { x: number; y: number };
15+
type P = keyof Point;
16+
// ^?
17+
```
18+
19+
If the type has a `string` or `number` index signature, `keyof` will return those types instead:
20+
21+
```ts twoslash
22+
type Arrayish = { [n: number]: unknown };
23+
type A = keyof Arrayish;
24+
// ^?
25+
26+
type Mapish = { [k: string]: boolean };
27+
type M = keyof Mapish;
28+
// ^?
29+
```
30+
31+
Note that in this example, `M` is `string | number` -- this is because JavaScript object keys are always coerced to a string, so `obj[0]` is always the same as `obj["0"]`.
32+
33+
`keyof` types become especially useful when combined with mapped types, which we'll learn more about later.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
title: Typeof Type Operator
3+
layout: docs
4+
permalink: /docs/handbook/2/typeof-types.html
5+
oneline: "Step one in learning TypeScript: The basics types."
6+
beta: true
7+
---
8+
9+
## The `typeof` type operator
10+
11+
JavaScript already has a `typeof` operator you can use in an _expression_ context:
12+
13+
```ts twoslash
14+
// Prints "string"
15+
console.log(typeof "Hello world");
16+
```
17+
18+
TypeScript adds a `typeof` operator you can use in a _type_ context to refer to the _type_ of a variable or property:
19+
20+
```ts twoslash
21+
let s = "hello";
22+
let n: typeof s;
23+
// ^?
24+
```
25+
26+
This isn't very useful for basic types, but combined with other type operators, you can use `typeof` to conveniently express many patterns.
27+
For an example, let's start by looking at the predefined type `ReturnType<T>`.
28+
It takes a _function type_ and produces its return type:
29+
30+
```ts twoslash
31+
type Predicate = (x: unknown) => boolean;
32+
type K = ReturnType<Predicate>;
33+
// ^?
34+
```
35+
36+
If we try to use `ReturnType` on a function name, we see an instructive error:
37+
38+
```ts twoslash
39+
// @errors: 2749
40+
function f() {
41+
return { x: 10, y: 3 };
42+
}
43+
type P = ReturnType<f>;
44+
```
45+
46+
Remember that _values_ and _types_ aren't the same thing.
47+
To refer to the _type_ that the _value `f`_ has, we use `typeof`:
48+
49+
```ts twoslash
50+
function f() {
51+
return { x: 10, y: 3 };
52+
}
53+
type P = ReturnType<typeof f>;
54+
// ^?
55+
```
56+
57+
### Limitations
58+
59+
TypeScript intentionally limits the sorts of expressions you can use `typeof` on.
60+
61+
Specifically, it's only legal to use `typeof` on identifiers (i.e. variable names) or their properties.
62+
This helps avoid the confusing trap of writing code you think is executing, but isn't:
63+
64+
```ts twoslash
65+
// @errors: 1005
66+
declare const msgbox: () => boolean;
67+
// type msgbox = any;
68+
// ---cut---
69+
// Meant to use =
70+
let shouldContinue: typeof msgbox("Are you sure you want to continue?");
71+
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
title: Creating Types from Types
3+
layout: docs
4+
permalink: /docs/handbook/2/types-from-types.html
5+
oneline: "Step one in learning TypeScript: The basics types."
6+
beta: true
7+
---
8+
9+
TypeScript's type system is very powerful because it allows expressing types _in terms of other types_.
10+
Although the simplest form of this is generics, we actually have a wide variety of _type operators_ available to us.
11+
It's also possible to express types in terms of _values_ that we already have.
12+
13+
By combining various type operators, we can express complex operations and values in a succinct, maintainable way.
14+
In this section we'll cover ways to express a type in terms of an existing type or value.

0 commit comments

Comments
 (0)