What you need to know about Typescript types
Tags: typescript, javascript, webdev, beginners
Published: 2022-04-11 10:11:44

When we are talking about types in typescript, what is the first thing that comes to your  mind? You may think:
- number (1,2,3)
- string ('hello',''world')
- boolean (true, false)
- object ({name:'Jon',age:'30'})
- function ((x,y)=> x + y) 
- undefined 
- null 
 
Yes, these are some possible types in Typescript system. Before you run the code, typescript uses them to check for errors.
 
A variable can just have one type... **_wow! stop there!_** you may start to argue with me now: "_typescript has **union type** and also **intersection type** which a variable can be assigned to several types! You are wrong Lucas!_" Yes, you are right about union and intersection type, but this is just one way to think of the types, and I prefer to think of the types in typescript as **a set of possible values.** For instance, a number type is a set of all number values. _2, 45, 1000_ belongs to it, but _'book', 'student'_ not. And depends on the [strictNullChecks](https://www.typescriptlang.org/tsconfig#strictNullChecks) setting, null and undefined may or may not be part of the set. (If the strictNullChecks is turned off, null and undefined are permissible values in every type.)

## Type Alias
 
The smallest type set is an empty set, which is an empty domain, no value can be found in it. It's also known as **Never** type in typescript, no values are assignable to a never type:
 
```
const A:never = 'a' // Error. Type 'string' is not assignable to type 'never'.
```
 
The next smallest type set contains a single value. There is only one single value that can be found in this domain, which 
corresponds to typescript **literal type**, also known as **unit type** :
 
```
type A = 'a'
type B = 'b'
type One = 1
 
const category:A = 'a' // Correct
const category:A = 'b' // Error, Type '"b"' is not assignable to type '"a"'.
```
 
And to form two or three values, you can use union unit types, which corresponds to typescript union type:
 
```
type AB = 'a' | 'b'
const A: AB = 'a' // Correct
const B: AB = 'b' // Correct
const C: AB = 'c' // Type '"c"' is not assignable to type 'AB'.
```
 
The values in these sets of values or domains are finite, it's quite easy to reason with. But most of time the domain we are dealing with is infinite, such as string, number or an interface, yet we still can think of them as a set of values:
 
```
type num = 1 | 2 | 3 | 4 | ... 
type str = 'apple' | 'banana' | 'book' | ...
```
The number type is the set of values of all the numbers in the universe, and the string type is the set of values of all the strings in the universe. 

## What does assignable mean?

How can this mindset help us understand better the Typescript's type system? I don't know if you ever encountered a situation when Typescript jumps out an error and it says: _Type A is not assignable to type B_ , and I am like: _What? the type A definitely can assign to type B._ This misunderstanding is because I didn't fully understand what typescript was trying to tell me. Here is a simple example:  
 
```
type Fruit = 'apple' | 'banana'
const log = (str:Fruit) =>  {
    console.log(str)
}
 
let myFruit = 'apple'
 
log(myFruit) // Error. Argument of type 'string' is not assignable to parameter of type 'Fruit'.
```

First of all, you may ask why a string is not assignable to type 'Fruit' which is also a string, 'apple' or 'banana'. The word **_'assignable'_** appears in many Typescript errors, in the context of set of values, it means either 'member of' or 'subset of'. So now we can translate the error message to _Argument of type 'string' is not a member of (subset of) parameter of type 'Fruit'._  If you are still asking is string a subset of type 'Fruit' or is type 'Fruit' a subset of string? You should think of types as a set of values. In the domain of string type contains infinite string values, on the other hand the type 'Fruit' only contains two values, 'apple' and 'banana'. So clearly type 'Fruit' is a subset of string, or string is the superset of type 'Fruit'. Now the error message makes sense to us, of course the string is not assignable to type 'Fruit'.
 
To fix the error is simple, we just change the keyword **let** to **const** , so Typescript will know the value 'apple' won't change in the future.

## Interface
 
Now let's take a look at the Typescript interface. Let's say we have two interfaces
 
```
interface AB {
  a:string
  b: string
}
 
interface ABC {
  a:string
  b: string
  c: string
}
```
Now my question is which interface is a subset of (a member of ) or assignable to another? You may immediately think: "interface AB is a subset of interface ABC, because inside interface ABC contains more values." But it's quite the opposite in this case, the correct answer is interface ABC is a subset of interface AB. That's because Javascript is inherently duck typed. And Typescript models this behavior. It means values with additional properties still belong to a type:
 
```
interface Person {
  name:string  
}
 
const person = {
  name:'aa',
  age:21,
  eyeColor:'blue'
}
 
const personA:Person = person // Correct
```
 
You also can verify it by creating an interface Union type:
 
```
interface Person {
  name:string  
}
 
interface ExtraInfo {
  job: string
  habit:string
  favouriteBook:string
}

type PersonInfo = Person | ExtraInfo
 
const personaB:PersonInfo = {
  name:'joe',
  job: 'developer',
  habit:'read',
  favouriteBook:'book'
} // Correct
```
As we know, **&** operator in Typescript computes the intersection of two types. Interface Person and ExtraInfo don't have common properties, but cause the duck typed behavior, _**values with additional properties still belong to a type**_  So the interface Union type will include all the properties in each interface. And you may surprisingly find an empty interface {} is the super set of all other interfaces, because it means it includes all the possible values. 
Back to our first question, I hope you have a clear idea now why the interface ABC is the subset of interface AB.