Skip to content

Commit 10431b4

Browse files
committed
I was doing a lot of stuff here
1 parent 97361f5 commit 10431b4

14 files changed

+162
-11
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@ Change an API? Change the type and you'll see everywhere you need to update. Nee
1111
TypeScript actively discourages highly-dynamic code, redefining variables to mean different things, and anything other than simple (property) strings for APIs. What do these look like?
1212

1313
```tsx
14-
// Dynamic code:
14+
// Dynamic code:
1515
```
1616

17-
18-
1917
# For Site / Application Developers
2018

2119
## I'm trying to start with an empty object and add properties one by one, and TypeScript gives me errors no matter what I do. I've given up and `// @ts-ignore`d them.
2220

2321
When you create an empty object, there's just no good way for TS to ensure that all properties have been added _after_ the object has already been specified. Don't worry, though - there are lots of ways to accomplish this, and one of them is very concise as well! See: [Build Up Object](examples/build-up-object.ts).
2422

23+
## What's this `never` type?
24+
25+
This is covered in the new handbook under the [never type](https://microsoft.github.io/TypeScript-New-Handbook/chapters/more-on-functions/#never).
26+
27+
Additionally, arrays start out as `never[]` when the type cannot be inferred. See: [Never](examples/never.ts)
28+
2529
## Why isn't TypeScript showing errors on extra properties I have on an object?
2630

2731
TypeScript has a system called "excess property checking" which is a great tradeoff between type safety and developer experience... provided you know how it works. Luckily, it's pretty simple. See: [Excess Property Checking](examples/excess-property-checking.ts).
@@ -74,7 +78,9 @@ This one trips up everyone at some point. There's an explanation at [Object.keys
7478

7579
## I don't control the object being used. How do I use the `object` type?
7680

81+
## How can I tell TypeScript about a global variable that exists without using @ts-ignore or `any`?
7782

83+
You're looking for the jargony `ambient context` and `ambient declaration`. When you put `declare` in front of a function, constant, or module, you are saying "trust me, this exists, and is of this type." This is especially confusing when looking at the differences between .d.ts and .ts files, so see [Types without implementations](examples/types-without-implementations.ts).
7884

7985
# React-Specific Errors
8086

examples/array-element-access.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// This seems wrong...
2+
const array = [0, 1];
3+
array[0];
4+
array[1];
5+
array[2]; // hey! this should be an error!
6+
7+
// but just like objects are mutable in TS, so are arrays.
8+
// Imagine this case:
9+
const pushToArray = <T>(arr: T[], element: T): T[] => {
10+
arr.push(element);
11+
return arr;
12+
};
13+
14+
const arr = [0, 1];
15+
pushToArray(arr, 2); // now arr[2] exists
16+
arr[2]; // if TS showed an error here, it would be extremely annoying
17+
18+
// TypeScript would have to do a lot more work to analyze your code to figure
19+
// out safe array access - and it's just not a common enough case to be worth
20+
// the cost.
21+
22+
// However, tuple types exist, which have a known length that can never change.
23+
// Checking access on these is cheap, so use `as const` to change from number[]
24+
// (array of numbers of any length) to [number, number] (array of numbers with
25+
// a length of 2).
26+
// (you'll see the term "const context" floating around: it means "immutable")
27+
const tuple = [0, 1] as const;
28+
29+
tuple[0];
30+
tuple[1];
31+
tuple[2]; // correctly an error

examples/definition-files.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// go over what's different about .d.ts
2+
3+
// declaration files
4+
5+
// first: if a declaration file is within

examples/definition-files.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

examples/error-codes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export {};
12
// https://github.com/Microsoft/TypeScript/blob/9c71eaf59040ae75343da8cdff01344020f5bba2/lib/diagnosticMessages.generated.json
23

34
const doStuff = (thing: "thing" | "stuff") => {};

examples/filter-reduce.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function toStrings(arr: object[]): string[] {
1313
acc.push(obj.toString());
1414
return acc;
1515
},
16-
[] as string[]
16+
[] as string[],
1717
);
1818
}
1919

@@ -32,7 +32,7 @@ interface User {
3232
}
3333
const fields = [
3434
{ name: "name", value: "bob" },
35-
{ name: "phone", value: "8005552000" }
35+
{ name: "phone", value: "8005552000" },
3636
] as const;
3737

3838
fields.reduce<User>((acc, field) => {
@@ -42,14 +42,17 @@ fields.reduce<User>((acc, field) => {
4242
}, {});
4343

4444
arr.reduce((acc, obj) => {
45+
// error: No index signature with a parameter of type 'number' was found on type '{}'
4546
acc[obj] = true;
4647
return acc;
4748
}, {});
4849

49-
const arrayWithNulls = [1, 2, null, undefined];
50+
const arrayWithNulls = [1, 2, null];
5051
// filter is a type guard = needs to explictly know how to remove the union
5152
const stillHasNulls: number[] = arrayWithNulls.filter(x => !!x);
52-
const withoutNulls: number[] = arrayWithNulls.filter((x): x is number => !!x);
53+
const withoutNulls: number[] = arrayWithNulls.filter(
54+
(x): x is number => x !== null,
55+
);
5356

5457
// since this is tedious, and boolean cast wipes out 0 and "" anyway:
5558
const filterNulls = Array.prototype.filter(item => item != null);

examples/generics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
// Let's use this above:
4545
() => {
4646
type Last<TItem> = (item: TItem) => TItem;
47-
const last = (item: string) => {
47+
const last: Last<> = item => {
4848
return item[item.length - 1];
4949
};
5050

examples/never.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export {};
2+
// The `never` type is a condition which should never happen.
3+
// This most commonly happens when a function throws an error, or when if/else/switch/case
4+
// runs out of options and hits an `else` or `default` case.
5+
6+
// from: https://microsoft.github.io/TypeScript-New-Handbook/chapters/more-on-functions/#never
7+
function fn(x: string | number) {
8+
if (typeof x === "string") {
9+
// do something
10+
} else if (typeof x === "number") {
11+
// do something else
12+
} else {
13+
x; // has type 'never'!
14+
}
15+
}
16+
17+
function fail(msg: string): never {
18+
throw new Error(msg);
19+
}
20+
21+
// The other time you'll see `never` is when creating a new empty array, when
22+
// noImplicityAny is set to `false`. It is extremely unlikely you will see this,
23+
// but the type defaults to `never[]` to prevent it from being inferred as `any[]`.
24+
// Simple fix: give it a type, or set `noImplicitAny` to true.
25+
// https://github.com/microsoft/TypeScript/pull/8944
26+
27+
const emptyArray = []; // never[]
28+
emptyArray.push(1); // nope!
29+
const emptyNumberArray: number[] = [];

examples/safe-property-access.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,6 @@ const doStuffWithUnions = (data?: UnreliableUnionData) => {
9595
const doStuffWithDefaults = (data: UnreliableData) => {
9696
// "Initializer provides no value for this binding element and the binding element has no default value.ts(2525)"
9797
const { nullableString }: UnreliableData["mayExist"] = data.mayExist || {};
98-
// This will be fixed when TypeScript 3.6 is released.
98+
// This will be fixed when TypeScript 3.6 is released:
99+
// https://github.com/microsoft/TypeScript/pull/31711
99100
};

examples/type-assertions.ts

Whitespace-only changes.

examples/types-without-implementations.ts

Whitespace-only changes.

examples/void.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export {};
2+
// The `void` is the absence of a type. It has one purpose: to
3+
// allow functions to return values which are ignored.
4+
// A practical use for this is an event handler which may want
5+
// to use a braceless arrow function.
6+
7+
// Contrast this with `undefined`, which enforces a return statement.
8+
type OnMouseEnter = () => void;
9+
const onMouseEnter: OnMouseEnter = () => false; // fine
10+
const returnValue = onMouseEnter(); // returnValue === void
11+
12+
type OnMouseLeave = () => undefined;
13+
const onMouseLeave: OnMouseLeave = () => false; // error: false !== undefined
14+
15+
// Note that void is more strict when put directly on a function.
16+
const returnUndefined = (): undefined => {
17+
return false; // error: false !== undefined
18+
};
19+
const returnVoid = (): void => {
20+
return false; // error: false !== void
21+
};

jargon.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Common Terms
2+
3+
## Structural Typing
4+
5+
## Subtype
6+
7+
In structural typing, a type which matches another type, but contains extra properties, is considered a subtype.
8+
In TypeScript
9+
Example:
10+
11+
```ts
12+
const;
13+
```
14+
15+
## Excess Property Checking
16+
17+
The
18+
19+
## Freshness
20+
21+
## Inference
22+
23+
## Invariant
24+
25+
## Type Parameter
26+
27+
Code which can be checked at runtime.
28+
29+
Type safe function:
30+
31+
```tsx
32+
const;
33+
```
34+
35+
## Type Safe
36+
37+
# Obscure Terms
38+
39+
## Covariant/Contravariant
40+
41+
# Really Obscure Terms
42+
43+
## Homomorphic
44+
45+
## Naked Type Parameter
46+
47+
A type parameter (see above) which is not wrapped in something like an array.
48+
49+
Example:
50+
51+
```ts
52+
// T here is any element in the array
53+
// T[] is the array itself
54+
const filter = <T>(array: T[], func: (T): boolean): T[] => {}
55+
```

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"allowJs": true,
3+
"allowJs": false,
44
"allowSyntheticDefaultImports": true,
55
"jsx": "preserve",
66
"lib": ["dom", "esnext"],

0 commit comments

Comments
 (0)