You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Add release notes
* Remove headers
* Add links to documentation for @types, --types and --typeRoots
Referenced in microsoft/TypeScript#11437 (comment)
* Update Compiler Options.md
Fix minor typo.
* Mention Babel at top of Gulp tutorial.
* IntelliJ Mac for nightly builds
Maybe include IntelliJ IDEA IDE for mac, too?
* Updated whitespaces and empty lines
* Use 'awesome-typescript-loader', use SFCs.
* Mentioned support for --outFile together with AMD or System
* Fixed broken link in React Webpack tutorial
Updated the path reference to the page about tsconfig.json as it was broken.
* Fixesmicrosoft#420
clarifies Do's and Don'ts Use Optional Parameters section
See https://gist.github.com/agrberg/7bf64c61d3c6de0c638e7c0bc4742000 for
more details
* Change </br> to <br/>
* Fixmicrosoft/TypeScript#10433
* Fixmicrosoft/vscode#14322
* Fix paths example: target should be "jquery", not "jquery.d.ts"
Also add missing closing braces and have all json consistently use 2 space indents.
* Port fix in microsoft#432
* Fix lint failure
* Fixed typo
* Invoke origin setter in Decorators.md
* Add object rest/spread
* Update compiler options for TS 2.1
* Review comments
* Fixmicrosoft#348
* Review comments
* Add TypeScript 2.1 release notes
* Reorder
* Fix typo
* Minor typo
* Document index and indexed access types
* Document mapped types
* Reword and reorder index types discussion
* Fix module import
* Grammar fix
* Review comments
* Simplify keyof
* Fix typos
* Reorder mapped types example
Based on the more involved discussion from the blog post.
* Minor edits from PR comments
* Discuss mapped type inference and call out terms better
* Move index and map types to end of Advanced Types
The feature depends on type aliases and string literal types, so
should come after those.
* Document [non-]nullable types
* Does not require `this.` before props in the stateless functional component example
* `Hello` must be exported to be used in `index.tsx`
* Removed typo square bracket
* Minor formatting tweak from PR comments
* Mention there are currently 2 webpack loaders for typescript and link to more information
Fixesmicrosoft#450
* Fix defaults for `--importHelpers`
* Add breaking change link to release-notes
* Fix typo in variable reference
* Fix two small errors in React + Webpack tutorial.
* fixing #12872, add a mistype to show the usage of optional properties
* Fix typos
* Change the phrasing on webpack typescript loaders to be more clear
* Update Interfaces.md
* Update Interfaces.md
* limit files to just the src directory
* Update 'include' in React guide.
Copy file name to clipboardExpand all lines: pages/Advanced Types.md
+315Lines changed: 315 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -283,6 +283,108 @@ The right side of the `instanceof` needs to be a constructor function, and TypeS
283
283
284
284
in that order.
285
285
286
+
# Nullable types
287
+
288
+
TypeScript has two special types, `null` and `undefined`, that have the values null and undefined respectively.
289
+
We mentioned these briefly in [the Basic Types section](./Basic Types.md).
290
+
By default, the type checker considers `null` and `undefined` assignable to anything.
291
+
Effectively, `null` and `undefined` are valid values of every type.
292
+
That means it's not possible to *stop* them from being assigned to any type, even when you would like to prevent it.
293
+
The inventor of `null`, Tony Hoare, calls this his ["billion dollar mistake"](https://en.wikipedia.org/wiki/Null_pointer#History).
294
+
295
+
The `--strictNullChecks` flag fixes this: when you declare a variable, it doesn't automatically include `null` or `undefined`.
296
+
You can include them explicitly using a union type:
297
+
298
+
```ts
299
+
let s ="foo";
300
+
s=null; // error, 'null' is not assignable to 'string'
301
+
let sn:string|null="bar";
302
+
sn=null; // ok
303
+
304
+
sn=undefined; // error, 'undefined' is not assignable to 'string | null'
305
+
```
306
+
307
+
Note that TypeScript treats `null` and `undefined` differently in order to match JavaScript semantics.
308
+
`string | null` is a different type than `string | undefined` and `string | undefined | null`.
309
+
310
+
## Optional parameters and properties
311
+
312
+
With `--strictNullChecks`, an optional parameter automatically adds `| undefined`:
313
+
314
+
```ts
315
+
function f(x:number, y?:number) {
316
+
returnx+ (y||0);
317
+
}
318
+
f(1, 2);
319
+
f(1);
320
+
f(1, undefined);
321
+
f(1, null); // error, 'null' is not assignable to 'number | undefined'
322
+
```
323
+
324
+
The same is true for optional properties:
325
+
326
+
```ts
327
+
classC {
328
+
a:number;
329
+
b?:number;
330
+
}
331
+
let c =newC();
332
+
c.a=12;
333
+
c.a=undefined; // error, 'undefined' is not assignable to 'number'
334
+
c.b=13;
335
+
c.b=undefined; // ok
336
+
c.b=null; // error, 'null' is not assignable to 'number | undefined'
337
+
```
338
+
339
+
## Type guards and type assertions
340
+
341
+
Since nullable types are implemented with a union, you need to use a type guard to get rid of the `null`.
342
+
Fortunately, this is the same code you'd write in JavaScript:
343
+
344
+
```ts
345
+
function f(sn:string|null):string {
346
+
if (sn==null) {
347
+
return"default";
348
+
}
349
+
else {
350
+
returnsn;
351
+
}
352
+
}
353
+
```
354
+
355
+
The `null` elimination is pretty obvious here, but you can use terser operators too:
356
+
357
+
```ts
358
+
function f(sn:string|null):string {
359
+
returnsn||"default";
360
+
}
361
+
```
362
+
363
+
In cases where the compiler can't eliminate `null` or `undefined`, you can use the type assertion operator to manually remove them.
364
+
The syntax is postfix `!`: `identifier!` removes `null` and `undefined` from the type of `identifier`:
365
+
366
+
```ts
367
+
function broken(name:string|null):string {
368
+
function postfix(epithet:string) {
369
+
returnname.charAt(0) +'. the '+epithet; // error, 'name' is possibly null
370
+
}
371
+
name=name||"Bob";
372
+
returnpostfix("great");
373
+
}
374
+
375
+
function fixed(name:string|null):string {
376
+
function postfix(epithet:string) {
377
+
returnname!.charAt(0) +'. the '+epithet; // ok
378
+
}
379
+
name=name||"Bob";
380
+
returnpostfix("great");
381
+
}
382
+
```
383
+
384
+
The example uses a nested function here because the compiler can't eliminate nulls inside a nested function (except immediately-invoked function expressions).
385
+
That's because it can't track all calls to the nested function, especially if you return it from the outer function.
386
+
Without knowing where the function is called, it can't know what the type of `name` will be at the time the body executes.
387
+
286
388
# Type Aliases
287
389
288
390
Type aliases create a new name for a type.
@@ -568,3 +670,216 @@ let v = new ScientificCalculator(2)
568
670
Without `this` types, `ScientificCalculator` would not have been able to extend `BasicCalculator` and keep the fluent interface.
569
671
`multiply` would have returned `BasicCalculator`, which doesn't have the `sin` method.
570
672
However, with `this` types, `multiply` returns `this`, which is `ScientificCalculator` here.
673
+
674
+
# Index types
675
+
676
+
With index types, you can get the compiler to check code that uses dynamic property names.
677
+
For example, a common Javascript pattern is to pick a subset of properties from an object:
678
+
679
+
```js
680
+
functionpluck(o, names) {
681
+
returnnames.map(n=> o[n]);
682
+
}
683
+
```
684
+
685
+
Here's how you would write and use this function in TypeScript, using the **index type query** and **indexed access** operators:
686
+
687
+
```ts
688
+
function pluck<T, KextendskeyofT>(o:T, names:K[]):T[K][] {
689
+
returnnames.map(n=>o[n]);
690
+
}
691
+
692
+
interfacePerson {
693
+
name:string;
694
+
age:number;
695
+
}
696
+
let person:Person;
697
+
let strings:string[] =pluck(person, ['name']); // ok, string[]
698
+
```
699
+
700
+
The compiler checks that `name` is actually a property on `Person`, and it knows that `strings` is a `string[]` because `name` is a `string`.
701
+
To make this work, the example introduces a couple of new type operators.
702
+
First is `keyof T`, the **index type query operator**.
703
+
For any type `T`, `keyof T` is the union of known, public property names of `T`.
704
+
For example:
705
+
706
+
```ts
707
+
let personProps:keyofPerson; // 'name' | 'age'
708
+
```
709
+
710
+
`keyof Person` is completely interchangeable with `'name' | 'age'`.
711
+
The difference is that if you add another property to `Person`, say `address: string`, then `keyof Person` will automatically update to be `'name' | 'age' | 'address'`.
712
+
And you can use `keyof` in generic contexts like `pluck`, where you can't possibly know the property names ahead of time.
713
+
That means the compiler will check that you pass the right set of property names to `pluck`:
714
+
715
+
```ts
716
+
pluck(person, ['age', 'unknown']); // error, 'unknown' is not in 'name' | 'age'
717
+
```
718
+
719
+
The second operator is `T[K]`, the **indexed access operator**.
720
+
Here, the type syntax reflects the expression syntax.
721
+
That means that `person['name']` has the type `Person['name']`— which in our example is just `string`.
722
+
However, just like index type queries, you can use `T[K]` in a generic context, which is where its real power comes to life.
723
+
You just have to make sure that the type variable `K extends keyof T`.
724
+
Here's another example with a function named `getProperty`.
725
+
726
+
```ts
727
+
function getProperty<T, KextendskeyofT>(o:T, name:K):T[K] {
728
+
returno[name]; // o[name] is of type T[K]
729
+
}
730
+
```
731
+
732
+
In `getProperty`, `o: T` and `name: K`, so that means `o[name]: T[K]`.
733
+
Once you return the T[K] result, the compiler will instantiate the actual type of the key, so the return type of `getProperty` will vary according to which property you request.
734
+
735
+
```ts
736
+
let name:string=getProperty(person, 'name');
737
+
let age:number=getProperty(person, 'age');
738
+
let unknown =getProperty(person, 'unknown'); // error, 'unknown' is not in 'name' | 'age'
739
+
```
740
+
741
+
## Index types and string index signatures
742
+
743
+
`keyof` and `T[K]` interact with string index signatures.
744
+
If you have a type with a string index signature, `keyof T` will just be `string`.
745
+
And `T[string]` is just the type of the index signature:
746
+
747
+
```ts
748
+
interfaceMap<T> {
749
+
[key:string]:T;
750
+
}
751
+
let keys:keyofMap<number>; // string
752
+
let value:Map<number>['foo']; // number
753
+
```
754
+
755
+
# Mapped types
756
+
757
+
A common task is to take an existing type and make each of its properties optional:
758
+
759
+
```ts
760
+
interfacePersonPartial {
761
+
name?:string;
762
+
age?:number;
763
+
}
764
+
```
765
+
766
+
Or we might want a readonly version:
767
+
768
+
```ts
769
+
interfacePersonReadonly {
770
+
readonly name:string;
771
+
readonly age:number;
772
+
}
773
+
```
774
+
775
+
This happens often enough in Javascript that TypeScript provides a way to create new types based on old types —**mapped types**.
776
+
In a mapped type, the new type transforms each property in the old type in the same way.
777
+
For example, you can make all properties of a type `readonly` or optional.
778
+
Here are a couple of examples:
779
+
780
+
```ts
781
+
typeReadonly<T> = {
782
+
readonly [PinkeyofT]:T[P];
783
+
}
784
+
typePartial<T> = {
785
+
[PinkeyofT]?:T[P];
786
+
}
787
+
```
788
+
789
+
And to use it:
790
+
791
+
```ts
792
+
typePersonPartial=Partial<Person>;
793
+
typeReadonlyPerson=Readonly<Person>;
794
+
```
795
+
796
+
Let's take a look at the simplest mapped type and its parts:
797
+
798
+
```ts
799
+
typeKeys='option1'|'option2';
800
+
typeFlags= { [KinKeys]:boolean };
801
+
```
802
+
803
+
The syntax resembles the syntax for index signatures with a `for .. in` inside.
804
+
There are three parts:
805
+
806
+
1. The type variable `K`, which gets bound to each property in turn.
807
+
2. The string literal union `Keys`, which contains the names of properties to iterate over.
808
+
3. The resulting type of the property.
809
+
810
+
In this simple example, `Keys` is a hard-coded list of property names and the property type is always `boolean`, so this mapped type is equivalent to writing:
811
+
812
+
```ts
813
+
typeFlags= {
814
+
option1:boolean;
815
+
option2:boolean;
816
+
}
817
+
```
818
+
819
+
Real applications, however, look like `Readonly` or `Partial` above.
820
+
They're based on some existing type, and they transform the fields in some way.
821
+
That's where `keyof` and indexed access types come in:
Copy file name to clipboardExpand all lines: pages/Basic Types.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -214,7 +214,7 @@ Once again, more on union types later on.
214
214
# Never
215
215
216
216
The `never` type represents the type of values that never occur.
217
-
For instance, `never` is the return type for a function expression or an arrow function expresssion that always throws an exception or one that never returns;
217
+
For instance, `never` is the return type for a function expression or an arrow function expression that always throws an exception or one that never returns;
218
218
Variables also acquire the type `never` when narrowed by any type guards that can never be true.
219
219
220
220
The `never` type is a subtype of, and assignable to, every type; however, *no* type is a subtype of, or assignable to, `never` (except `never` itself).
Copy file name to clipboardExpand all lines: pages/Classes.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Introduction
2
2
3
-
Traditional JavaScript focuses on functions and prototype-based inheritance as the basic means of building up reusable components, but this may feel a bit awkward to programmers more comfortable with an object-oriented approach, where classes inherit functionality and objects are built from these classes.
3
+
Traditional JavaScript uses functions and prototype-based inheritance to build up reusable components, but this may feel a bit awkward to programmers more comfortable with an object-oriented approach, where classes inherit functionality and objects are built from these classes.
4
4
Starting with ECMAScript 2015, also known as ECMAScript 6, JavaScript programmers will be able to build their applications using this object-oriented class-based approach.
5
5
In TypeScript, we allow developers to use these techniques now, and compile them down to JavaScript that works across all major browsers and platforms, without having to wait for the next version of JavaScript.
0 commit comments