Skip to content
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

Fix Syntax/Grammar Errors #699

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
10 changes: 5 additions & 5 deletions docs/errors/common-errors.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# Common Errors
In this section we explain a number of common error codes that users experience in the real world.
In this section, we explain several common error codes that users experience in the real world.

## TS2304
Samples:
> `Cannot find name ga`
> `Cannot find name $`
> `Cannot find module jquery`

You are probably using a third party library (e.g. google analytics) and don't have it `declare`d. TypeScript tries to save you from *spelling mistakes* and *using variables without declaring them* so you need to be explicit on anything that is *available at runtime* because of you including some external library ([more on how to fix it][ambient]).
You are probably using a third-party library (e.g. Google Analytics) and don't have it `declare`d. TypeScript tries to save you from *spelling mistakes* and *using variables without declaring them* so you need to be explicit about anything that is *available at runtime* because you include some external library ([more on how to fix it][ambient]).

## TS2307
Samples:
> `Cannot find module 'underscore'`

You are probably using a third party library (e.g. underscore) as a *module* ([more on modules][modules]) and don't have the ambient declaration file for it ([more on ambient declarations][ambient]).
You are probably using a third-party library (e.g. underscore) as a *module* ([more on modules][modules]) and don't have the ambient declaration file for it ([more on ambient declarations][ambient]).

## TS1148
Sample:
> Cannot compile modules unless the '--module' flag is provided

Checkout the [section on modules][modules].
Check out the [section on modules][modules].

## Catch clause variable cannot have a type annotation
Sample:
Expand All @@ -34,7 +34,7 @@ try { something(); }
catch (e) {
if (e instanceof Error){
// Here you go.
}
}
}
```

Expand Down
18 changes: 9 additions & 9 deletions docs/errors/interpreting-errors.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Interpreting Errors
Since TypeScript is a heavily focused *Developer Help* oriented programming language, its errors messages try to be super helpful when something goes wrong. This can lead to a slight information overload for unsuspecting users of compilers that aren't so helpful.
Since TypeScript is a heavily focused *Developer Help* oriented programming language, its error messages try to be super helpful when something goes wrong. This can lead to a slight information overload for unsuspecting users of compilers that aren't so helpful.

Lets look at an example in an IDE to break apart the process of reading an error message.
Let's look at an example in an IDE to break apart the process of reading an error message.

```ts
type SomethingComplex = {
Expand All @@ -25,29 +25,29 @@ const fail = {
takeSomethingComplex(fail); // TS ERROR HAPPENS HERE
```

This example demonstrates a common programmer error where they *fail* to call a function (`bar: getBar` should be `bar: getBar()`). Fortunately this mistake is caught by TypeScript as soon as it doesn't meet the type requirements.
This example demonstrates a common programmer error where they *fail* to call a function (`bar: getBar` should be `bar: getBar()`). Fortunately, this mistake is caught by TypeScript as soon as it doesn't meet the type requirements.

## Error Categories
There are two categories of TypeScript Error messages (succinct and detailed).

### Succinct
The objective of the succinct error message is to provide an example *conventional compiler* description of the error number and message. For this example the succinct message looks like:
The objective of the succinct error message is to provide an example *conventional compiler* description of the error number and message. For this example, the succinct message looks like:

```
TS2345: Argument of type '{ foo: number; bar: () => string; }' is not assignable to parameter of type 'SomethingComplex'.
```
It is fairly self explanatory. However, it doesn't provide a deeper breakdown of *why* the error is happening. That is what the *detailed* error message is for.
It is fairly self-explanatory. However, it doesn't provide a deeper breakdown of *why* the error is happening. That is what the *detailed* error message is for.

### Detailed
For this example the detailed version looks like:
For this example, the detailed version looks like:

```
[ts]
Argument of type '{ foo: number; bar: () => string; }' is not assignable to parameter of type 'SomethingComplex'.
Types of property 'bar' are incompatible.
Type '() => string' is not assignable to type 'string'.
Types of property 'bar' are incompatible.
Type '() => string' is not assignable to type 'string'.
```
The objective of the detailed error message is to *guide* the user to the reason why some error (type incompatibility in this case) is happening. The first line is same as the succinct, followed by a chain. You should read this chain as a series of responses to the developer question `WHY?` between lines i.e
The objective of the detailed error message is to *guide* the user to the reason why some error (type incompatibility in this case) is happening. The first line is the same as the succinct, followed by a chain. You should read this chain as a series of responses to the developer's question `WHY?` between lines i.e

```
ERROR: Argument of type '{ foo: number; bar: () => string; }' is not assignable to parameter of type 'SomethingComplex'.
Expand Down
2 changes: 1 addition & 1 deletion docs/errors/main.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Errors
In this section we discuss how to read and understand TypeScript errors. We follow this with common errors and their solutions.
In this section, we discuss how to read and understand TypeScript errors. We follow this with common errors and their solutions.
12 changes: 6 additions & 6 deletions docs/javascript/closure.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function outerFunction(arg) {

function bar() {
console.log(variableInOuterFunction); // Access a variable from the outer scope
}
}

// Call the local function to demonstrate that it has access to arg
bar();
Expand All @@ -19,14 +19,14 @@ outerFunction("hello closure"); // logs hello closure!

You can see that the inner function has access to a variable (variableInOuterFunction) from the outer scope. The variables in the outer function have been closed by (or bound in) the inner function. Hence the term **closure**. The concept in itself is simple enough and pretty intuitive.

Now the awesome part: The inner function can access the variables from the outer scope *even after the outer function has returned*. This is because the variables are still bound in the inner function and not dependent on the outer function. Again let's look at an example:
Now the awesome part: The inner function can access the variables from the outer scope *even after the outer function has returned*. This is because the variables are still bound to the inner function and not dependent on the outer function. Again let's look at an example:

```ts
function outerFunction(arg) {
var variableInOuterFunction = arg;
return function() {
console.log(variableInOuterFunction);
}
}
}

var innerFunction = outerFunction("hello closure!");
Expand All @@ -44,7 +44,7 @@ function createCounter() {
return {
increment() { val++ },
getVal() { return val }
}
}
}

let counter = createCounter();
Expand All @@ -54,14 +54,14 @@ counter.increment();
console.log(counter.getVal()); // 2
```

At a high level it is also what makes something like Node.js possible (don't worry if it doesn't click in your brain right now. It will eventually 🌹):
At a high level, it is also what makes something like Node.js possible (don't worry if it doesn't click in your brain right now. It will eventually 🌹):

```ts
// Pseudo code to explain the concept
server.on(function handler(req, res) {
loadData(req.id).then(function(data) {
// the `res` has been closed over and is available
res.send(data);
})
})
});
```
10 changes: 5 additions & 5 deletions docs/javascript/equality.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ console.log(5 == "5"); // true , TS Error
console.log(5 === "5"); // false , TS Error
```

However, the choices JavaScript makes are not always ideal. For example, in the below example the first statement is false
However, the choices JavaScript makes are not always ideal. For example, in the example below, the first statement is false
because `""` and `"0"` are both strings and are clearly not equal. However, in the second case both `0` and the
empty string (`""`) are falsy (i.e. behave like `false`) and are therefore equal with respect to `==`. Both statements
are false when you use `===`.
Expand Down Expand Up @@ -51,14 +51,14 @@ type IdDisplay = {
display: string
}
const list: IdDisplay[] = [
{
{
id: 'foo',
display: 'Foo Select'
},
{
},
{
id: 'bar',
display: 'Bar Select'
},
},
]

const fooIndex = list.map(i => i.id).indexOf('foo');
Expand Down
23 changes: 12 additions & 11 deletions docs/javascript/null-undefined.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

> [Free youtube video on the subject](https://www.youtube.com/watch?v=kaUfBNzuUAI)

JavaScript (and by extension TypeScript) has two bottom types : `null` and `undefined`. They are *intended* to mean different things:
JavaScript (and by extension TypeScript) has two bottom types: `null` and `undefined`. They are *intended* to mean different things:

* Something hasn't been initialized : `undefined`.
* Something hasn't been initialized: `undefined`.
* Something is currently unavailable: `null`.


### Checking for either

Fact is you will need to deal with both. Interestingly in JavaScript with `==`, `null` and `undefined` are only equal to each other:
The fact is you will need to deal with both. Interestingly in JavaScript with `==`, `null` and `undefined` are only equal to each other:

```ts
// Both null and undefined are only `==` to themselves and each other:
Expand All @@ -30,19 +30,19 @@ Recommend `== null` to check for both `undefined` or `null`. You generally don't
function foo(arg: string | null | undefined) {
if (arg != null) {
// arg must be a string as `!=` rules out both null and undefined.
}
}
}
```

> You could also do `== undefined`, but `== null` is more conventional/shorter.

One exception, root level `undefined` values which we discuss next.
One exception is root level `undefined` values which we discuss next.

### Checking for root level undefined

Remember how I said you should use `== null`? Of course you do (cause I just said it ^). Don't use it for root level things. In strict mode if you use `foo` and `foo` is undefined you get a `ReferenceError` **exception** and the whole call stack unwinds.
Remember how I said you should use `== null`? Of course, you do (cause I just said it ^). Don't use it for root level things. In strict mode if you use `foo` and `foo` is undefined you get a `ReferenceError` **exception** and the whole call stack unwinds.

> You should use strict mode ... and in fact the TS compiler will insert it for you if you use modules ... more on those later in the book so you don't have to be explicit about it :)
> You should use strict mode ... and in fact, the TS compiler will insert it for you if you use modules ... more on those later in the book so you don't have to be explicit about it :)

So to check if a variable is defined or not at a *global* level you normally use `typeof`:

Expand All @@ -54,14 +54,15 @@ if (typeof someglobal !== 'undefined') {
```

### Limit explicit use of `undefined`
Because TypeScript gives you the opportunity to *document* your structures separately from values instead of stuff like:
Because TypeScript allows you to *document* your structures separately from values instead of stuff like:
```ts
function foo(){
// if Something
return {a:1,b:2};
// else
return {a:1,b:undefined};
}

```
you should use a type annotation:
```ts
Expand All @@ -74,7 +75,7 @@ function foo():{a:number,b?:number}{
```

### Node style callbacks
Node style callback functions (e.g. `(err,somethingElse)=>{ /* something */ }`) are generally called with `err` set to `null` if there isn't an error. You generally just use a truthy check for this anyways:
Node style callback functions (e.g. `(err,somethingElse)=>{ /* something */ }`) are generally called with `err` set to `null` if there isn't an error. You generally just use a truthy check for this anyway:

```ts
fs.readFile('someFile', 'utf8', (err,data) => {
Expand All @@ -85,7 +86,7 @@ fs.readFile('someFile', 'utf8', (err,data) => {
}
});
```
When creating your own APIs it's *okay* to use `null` in this case for consistency. In all sincerity for your own APIs you should look at promises, in that case you actually don't need to bother with absent error values (you handle them with `.then` vs. `.catch`).
When creating your own APIs it's *okay* to use `null` in this case for consistency. In all sincerity for your own APIs you should look at promises, in that case, you actually don't need to bother with absent error values (you handle them with `.then` vs. `.catch`).

### Don't use `undefined` as a means of denoting *validity*

Expand Down Expand Up @@ -124,4 +125,4 @@ Setting attribute values to undefined can save on storage and transmission costs
### Final thoughts
TypeScript team doesn't use `null` : [TypeScript coding guidelines](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined) and it hasn't caused any problems. Douglas Crockford thinks [`null` is a bad idea](https://www.youtube.com/watch?v=PSGEjv3Tqo0&feature=youtu.be&t=9m21s) and we should all just use `undefined`.

However, NodeJS style code bases uses `null` for Error arguments as standard as it denotes `Something is currently unavailable`. I personally don't care to distinguish between the two as most projects use libraries with differing opinions and just rule out both with `== null`.
However, NodeJS style code bases use `null` for Error arguments as standard as it denotes `Something is currently unavailable`. I personally don't care to distinguish between the two as most projects use libraries with differing opinions and just rule out both with `== null`.
14 changes: 7 additions & 7 deletions docs/javascript/number.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Whenever you are handling numbers in any programming language you need to be awa
JavaScript has only one number type. It is a double-precision 64-bit `Number`. Below we discuss its limitations along with a recommended solution.

### Decimal
For those familiar with doubles / float in other languages, you would know that binary floating point numbers *do not* map correctly to Decimal numbers. A trivial (and famous) example with JavaScript's built in numbers is shown below:
For those familiar with doubles/float in other languages, you would know that binary floating point numbers *do not* map correctly to Decimal numbers. A trivial (and famous) example with JavaScript's built-in numbers is shown below:

```js
console.log(.1 + .2); // 0.30000000000000004
Expand All @@ -14,7 +14,7 @@ console.log(.1 + .2); // 0.30000000000000004
> For true decimal math use `big.js` mentioned below.

### Integer
The integer limits represented by the built in number type are `Number.MAX_SAFE_INTEGER` and `Number.MIN_SAFE_INTEGER`.
The integer limits represented by the built-in number type are `Number.MAX_SAFE_INTEGER` and `Number.MIN_SAFE_INTEGER`.

```js
console.log({max: Number.MAX_SAFE_INTEGER, min: Number.MIN_SAFE_INTEGER});
Expand All @@ -23,7 +23,7 @@ console.log({max: Number.MAX_SAFE_INTEGER, min: Number.MIN_SAFE_INTEGER});

**Safe** in this context refers to the fact that the value *cannot be the result of a rounding error*.

The unsafe values are `+1 / -1` away from these safe values and any amount of addition / subtraction will *round* the result.
The unsafe values are `+1 / -1` away from these safe values and any amount of addition/subtraction will *round* the result.

```js
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true!
Expand Down Expand Up @@ -52,7 +52,7 @@ console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 10)); // false
> JavaScript will eventually get [BigInt](https://developers.google.com/web/updates/2018/05/bigint) support. For now, if you want arbitrary precision integer math use `big.js` mentioned below.

### big.js
Whenever you use math for financial calculations (e.g. GST calculation, money with cents, addition etc) use a library like [big.js](https://github.com/MikeMcl/big.js/) which is designed for
Whenever you use math for financial calculations (e.g. GST calculation, money with cents, addition, etc) use a library like [big.js](https://github.com/MikeMcl/big.js/) which is designed for
* Perfect decimal math
* Safe out of bound integer values

Expand All @@ -73,7 +73,7 @@ export const bar = foo.plus(new Big('0.00000000000000000001'));
const x: number = Number(bar.toString()); // Loses the precision
```

> Do not use this library for math used for UI / performance intensive purposes e.g charts, canvas drawing etc.
> Do not use this library for math used for UI / performance-intensive purposes e.g. charts, canvas drawing, etc.

### NaN
When some number calculation is not representable by a valid number, JavaScript returns a special `NaN` value. A classic example is imaginary numbers:
Expand Down Expand Up @@ -114,7 +114,7 @@ console.log(Number.MAX_VALUE + 1e292); // Infinity
console.log(-Number.MAX_VALUE - 1e292); // -Infinity
```

Of-course, these special infinity values also show up with arithmetic that requires it e.g.
Of course, these special infinity values also show up with arithmetic that requires it e.g.

```js
console.log( 1 / 0); // Infinity
Expand All @@ -128,7 +128,7 @@ console.log(Number.POSITIVE_INFINITY === Infinity); // true
console.log(Number.NEGATIVE_INFINITY === -Infinity); // true
```

Fortunately comparison operators (`<` / `>`) work reliably on infinity values:
Fortunately, comparison operators (`<` / `>`) work reliably on infinity values:

```js
console.log( Infinity > 1); // true
Expand Down
6 changes: 3 additions & 3 deletions docs/javascript/recap.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ There were (and will continue to be) a lot of competitors in *Some syntax* to *J

However, it does mean that *you need to learn JavaScript* (the good news is *you **only** need to learn JavaScript*). TypeScript is just standardizing all the ways you provide *good documentation* on JavaScript.

* Just giving you a new syntax doesn't help catch bugs - but might help you write cleaner / less bugs (e.g. CoffeeScript).
* Creating a new language abstracts you too far from your runtimes and communities - but might help on-board you easier if its an already familiar flavour (e.g. Dart - closer for Java / C# devs).
* Just giving you a new syntax doesn't help catch bugs - but might help you write cleaner / fewer bugs (e.g. CoffeeScript).
* Creating a new language abstracts you too far from your runtimes and communities - but might help onboard you easier if it's an already familiar flavour (e.g. Dart - closer for Java / C# devs).

TypeScript is just JavaScript with docs.

Expand Down Expand Up @@ -36,7 +36,7 @@ function add(a,b) {
}
```

Essentially TypeScript is linting JavaScript. Just doing a better job at it than other linters that don't have *type information*.
Essentially TypeScript is linting JavaScript, doing a better job at it than other linters that don't have *type information*.

## You still need to learn JavaScript

Expand Down
2 changes: 1 addition & 1 deletion docs/javascript/references.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## References

Beyond literals, any Object in JavaScript (including functions, arrays, regexp etc) are references. This means the following
Beyond literals, any Objects in JavaScript (including functions, arrays, regexp, etc) are references. This means the following:

### Mutations are across all references

Expand Down
2 changes: 1 addition & 1 deletion docs/javascript/this.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## this

Any access to `this` keyword within a function is controlled by how the function is actually called. It is commonly referred to as the “calling context.”
Any access to `this` keyword within a function is controlled by how the function is called. It is commonly referred to as the “calling context.”

Here is an example:

Expand Down
Loading