Typescript Newish Features
Tags: typescript, javascript
Published: 2020-12-29 18:04:29


Introducing useful Typescript features arrived with 3.7 and later

I learned these from the Frontend Masters course, definitely recommended 👍

[Production Grade Typescript](https://frontendmasters.com/courses/production-typescript)



### Recursive Type References (3.7)
 For example, this was not feasible in 3.6:
``` 
type ValueOrArray<T> = T | Array<ValueOrArray<T>>; 
```

Now type declarations can recursively reference themselves.

### Optional Chaining (3.7)
```
type ContactDetails =  {
    name: string,
    phone: string,
    address?: {
        city: string,
        street?: string,
    }
}
const myOtherFriend : ContactDetails = { name:'Some Guy', phone:'0123456766'}
console.log(myOtherFriend.address?.street);
```

### Nullish Coalescing (3.7)
raw name is either undefined or null, not empty string, false values

```
this.name = rawName ?? '(no name)';

```


### Private class fields (3.8)
3.8 adds private fields, which are a way of declaring a class field to
be unavailable outside of the containing class, including to subclasses.

```
class Foo {
  #name:string;
  constructor() {
    this.#name = 'whatever'; //ok here
  }  
}
const myVal = new Foo();
myVal.#name // Error! can't access name outside class Foo;
```

### ReExport from (3.8)
With 3.8, TypeScript supports more of the export
statement forms in the JavaScript specs, letting
you write a single line to re-export a module

```
export * as jestConsole from "@jest/console";
export * as jestReporters from "@jest/reporters";
```

### Variadic Tuple Types (4.0)
A variadic tuple type is a tuple type that has the same properties - defined length and the type of each element is known - but where the exact shape is yet to be defined.

The first change is that spreads in tuple type syntax can now be generic.
```

// spreads in tuples can be generic now
type GenericTuple<S extends unknown[]> = [first:number,  ...spread:S,  last: string];

const foo:GenericTuple<[boolean, string]> = [12,false,'aaa','aaa'];
const bar:GenericTuple<[number, string, boolean]> = [13,1,'bbb', false,'ccc'];


```

The second change is that rest elements can occur anywhere in a tuple – not just at the end!

```
type Strings = [string, string];
type Numbers = [number, number];

// [string, string, number, number, boolean]
type StrStrNumNumBool = [...Strings, ...Numbers, boolean];

```


### Labeled tuple types (4.0)

old style tuple declaration

```
type Address = [ number, string, string, number];
```

vs this

```
type Address = [streetNumber: number, streetName: string, houseName: string, houseNumber: number];

```

now you can see tuple variables labels in intellisense

instead of this
```
printAddress(/*address_0*/54,/*address_1*/'regents street',/*address_2*/'whitehouse', /*address_3*/12)
```
you get this..
```
printAddress(/*streetNumber*/54,/*streeName*/'regents street',/*houseName*/'whitehouse', /*houseNumber*/12)
```

### Template type literals (4.1)

```
type Features = "Redesign" | "newArtistPage";
```
4.1 supports a set of new generic-like keywords which
you can use inside a template literal to manipulate strings.
These are: Uppercase, Lowercase, Capitalize and Uncapitalize

```
type FeatureID = `${Lowercase<Features>}-id`;
type FeatureEnvVar = `${Uppercase<Features>}-ID`;

const z: FeatureID = 'redesign-id'; //works
const t: FeatureID = 'Redesign-id'; //not valid
```