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 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.
Top comments (1)
An incredible world of excitement awaits you at Duelz Casino, which can guarantee the best gambling experience in the UK. Start your adventure by searching for gambling games. There are many options here: from classic to modern. Start your adventure now to enjoy every minute of it. You can easily find the atmosphere of excitement that you so desire using the link.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.