Intersecting Interfaces0:41
We have another interface called Identifiable. And all it means for something to be Identifiable is that it has a UUID that is a string. So we can now create some new object called something. And we can say it is the intersection of Serializable and Identifiable. So basically you can just read this how it reads in English. It's Serializable and it's Identifiable. So it needs to have a UUID for it to be Identifiable. And it needs to have this serialize function to make it Serializable. So we basically just take X and we return the stringified version of X. And now if I were to remove one of these properties by, say, commenting out the UUID,
Reading Missing Property Errors1:10
So we basically just take X and we return the stringified version of X. And now if I were to remove one of these properties by, say, commenting out the UUID, we get a really helpful error message. Again, for TypeScript, just jump straight to the last line. It's usually going to tell you what you need. Property UUID is missing but required in type Identifiable. So it just tells us we need a UUID. If we comment out serialize, we'll look at the error. We'll jump straight to the last line. Property serialize is missing but required in type Serializable.
Defining Dictionary Types2:33
So something that satisfies this dictionary type. An object like this. So this is a valid dictionary. We have a key, which is a string. It has a value, which is a string. And we could actually have any number of these. It doesn't matter. This isn't just saying we have one. It's saying we just have everything within the item is only composed of keys of strings and values of strings.
Index Signatures and Constraints2:58
It's saying we just have everything within the item is only composed of keys of string and values of string. So we couldn't do this. We couldn't give it a key of not a string and the number 1. This wouldn't work because it basically says the type number is not assignable to type string. The expected types come from this index signature. So if you're looking for this in the TypeScript documentation, it comes under index signatures. And you're basically saying everything in a dictionary has to have a key of string and a body of string. So this is going to fail because it has a value of number. Now, the more modern way to write this or the more common way, the more concise way, the way I prefer,
Using Record and Unknown4:34
It can be a function. It can really be anything. So we generally type this as unknown. And this is a very, very flexible type declaration for when you have data types that you want to be very flexible, like an API payload, you could use this type here. So basically, the point I'm trying to make is when you take the intersection of types, they have to be compatible. It's not obvious necessarily when you look at this type if you're not used to it. But this is saying that everything inside the item has to have a key string and a value string. So let's use this record syntax to be more concise. But I'm going to intersect an interface like this.
Intersection Compatibility Pitfalls5:09
So let's use this record syntax to be more concise. But I'm going to intersect an interface like this. A TTL of number. This is equal to foo and record string string. This isn't actually going to error because TypeScript unfortunately can't really tell you this is not valid. But if I were to try and make a constant of type note and do something like this, TTL is going to be 100. Name is going to be yes. This is not a valid type. This is basically saying type number is not assignable to type string. Again, just drop to the bottom line.
