#
a()
- Mix: Provide a type consistent with the result of
Object.assign(A, B)
#
addNumbers(a, b)
Add three numbers
Parameters
| Name |
Types |
Description |
| a |
|
first number |
| b |
|
second |
#
timeout(n)
Create a promise that resolves after some time
Parameters
| Name |
Types |
Description |
| n |
|
number of milliseconds before promise resolves |
#
aa()
(8) simple array types can be expressed using []
#
bb()
(9) we can even define a tuple, which has a fixed length
#
cc()
(11) object types can be expressed using {} and property names
#
dd()
(12) You can use the optional operator (?) to indicate that something may or may not be there
#
otherContactInfo()
(15) Intersection types
#
PhoneNumber()
(14) Union types Sometimes we have a type that can be one of several things
#
x()
(1) x is a string, b/c we’ve initialized it
#
xx()
(10) Tuple values often require type annotations ( : [number, number] )
#
y()
(4) let's look at const. The type is literally 'hello world'
#
z()
(5) sometimes we need to declare a variable w/o initializing it
#
zz()
(7) we could improve this situation by providing a type annotation when we declare our variable
#
InternationalPhoneNumber()
(2) Interfaces can extend from other interfaces
#
AbstractContact()
(5) TypeScript even allows for abstract classes, which have a partial implementation
#
ConcreteContact()
(6) implementors must "fill in" any abstract methods or properties
#
Contact()
(1) Classes work similarly to what you're used to seeing in JS - They can "implement" interfaces
#
OtherContact()
(4) Class fields can have initializers (defaults)
#
ParamPropContact()
(3) Access modifier keywords - "who can access this thing" - public - everyone - protected - me and subclasses - private - only me
#
Array.filter()
(2) Type parameters can have default types - just like function parameters can have default values
#
arrayToDict()
(4) Type parameters can have constraints
#
resolveOrTimeout()
(3) You don't have to use exactly your type parameter as an arg - things that are based on your type parameter are fine too
#
startTuple()
(5) Type parameters are associated with scopes, just like function arguments
#
aa()
(6) Dealing with multiple unknowns - We kind of lose some of the benefits of structural typing when using unknown. - Look how we can get mixed up below
#
if()
(4) Built-in type guards
#
logWhenResolved()
(2) When to use any Anys are good for areas of our programs where we want maximum flexibility Example: sometimes a Promise is fine when we don't care at all about the resolved value
#
myAny()
(1) "Top types" are types that can hold any value. Typescript has two of them
#
myUnknown.split()
(3) When to use unknown Unknowns are good for "private" values that we don't want to expose through a public API. They can still hold any value, we just must narrow the type before we're able to use it. We'll do htis with a type guard.
#
n()
(8) Bottom types can hold no values. TypeScript has one of these: never
#
UnreachableError()
(9) We can use this to our advantage to create exhaustive conditionals and switches
#
x()
A common place where you'll end up with a never is through narrowing exhaustively
#
alreadyResolvedNum()
(2) Type queries allow us to obtain the type from a value using typeof
#
Email()
(4) Partial allows us to make all properties on an object optional
#
Then()
(5) Pick allows us to select one or more properties from an object type
#
Album()
(5) declarations with the same name can be merged, to occupy the same identifier
#
Contact()
(4) Classes are both types and values
#
foo()
(1) "identifiers" (i.e., a variable, class, function, interface) - can be associated with three things: value, type and namespace
#
ses()
(6) Namespaces have their own slot, and are also values
#
xx()
(2) Functions and variables are purely values. - Their types may only be extracted using type queries