

Discover more from All Things Typescript
If it looks like a duck, walks like a duck, quack like a duck... All Things Typescript Newsletter - Issue #21
In this issue of All Things Typescript, we are going to explore Structural Typing in Typescript and it's benefits.
Good morning; I hope you had a fantastic weekend. On a personal note, I had a fantastic week last week, and I am very excited to say that I am now a Google Developer Expert for Angular.


This is the 21st issue of All Things Typescript, and I am making some changes to the makeup of the issues. Starting from this issue, I am breaking out hand-picked content (Articles, Tweets, etc.) into its section. When I started this newsletter a few months back, I only had hand-picked content from other authors. Since then, it has evolved to include weekly lessons. And on top of that, I have also added a mid-week scoop section, going out in the middle of the week for discussions and learning.
This section will contain hand-picked content related to Typescript from other authors across the web that I have read within the week. This will go out weekly (on Friday), meaning you will receive three newsletters every week from All Things Typescript, containing rich content to help build a better understanding of Typescript.
All Things Typescript Virtual Workshop
I am working on a few Typescript virtual workshops for developers looking to improve their Typescript skills. I have a small survey collecting feedback to gauge interest and determine the curriculum for the first few workshops in September and October. Please take a moment and fill in the survey to help me build a kickass workshop for developers like you.
Structural Typing in Typescript - If it looks like a duck, walks like a duck, quacks like a duck β¦
How do you test whether a bird is a duck? One approach would be to ask a series of questions, and the answers would dictate whether itβs a duck:
Does it look like a duck?
Does it walk like a duck?
Does it quack like a duck?
If the answer to all those questions is yes, then we can conclude it must be a duck. We are checking whether the bird in question models the behavior we expect from a duck, and if it matches up, we can then conclude itβs a duck with a certain level of certainty. This is popularly known as the duck test, and Typescript type checking operates similarly. This is known as structural typing or property-based typing.
Letβs take an example of this. Letβs take the following two types:
type Person = {
firstName: string;
lastName: string;
}
type PersonWithAge = {
firstName: string;
lastName: string;
age: number;
}
The difference between type Person
nd PersonWithAge
, is that the second one has an extra field: age
. What do you think happens if we tried to assign a variable of type PersonWithAge
to a variable of type Person
?
const personWithAge: PersonWithAge = {
age: 20,
firstName: "John",
lastName: "Doe"
};
const person: Person = personWithAge;
Nothing, Typescript doesnβt throw an error and is okay with that, but why? Typescript uses Structural Typing, and just like our duck test above, if all the properties required by the type of the variable itβs being assigned to are there and have the same type, Typescript and, by extension Javascript, doesnβt care how the object was created.
There are situations where Typescript will complain if you have excess properties and you can learn more about that here.
Understanding this and its implications is very important. For instance, Typescript doesnβt guarantee that an object will not have excess properties; as long as the required fields are present and with the same type as the corresponding field, Typescript will be okay, and it can lead to you sending excessive data to another system or exposing data you didnβt intend to.
Structural typing can also have surprising results. For instance, take the following class:
class Person {
firstName: string;
lastName: string;
constructor() {
this.firstName = "John"
this.lastName = "Doe"
}
}
What happens when we do something like this?
const personObj = {
firstName: "Jane",
lastName: "Doe"
}
const personClass: Person = personObj;
Typescript doesnβt complain even though we are assigning an object to a class. Why? This is because the object has firstName
and lastName
just like the class plus a constructor from Object.protype
. I wonβt delve into this more in this issue, but you can learn more here.
One of the benefits of structural typing is when you are writing tests. Letβs use AWS DynamoDB DocumentClient Client as an example. If we wanted to save some items to the Database, we could pass a client whose type contains only properties of the DocumentClient class we are using:
function save(client: { put: () => {} }) {
// code here
}
This allows us to pass in the actual DocumentCliient from our code, but when testing, we can create a smaller mock object that we can pass in instead. We can even use the Pick
utility type to pick only the needed fields.
function save(client: Pick<DocumentClient, "put">) {
// code here
}
Here is another article that highlights the benefits of structural typing in testing.
Conclusion
In this issue of All Things Typescript, we looked at structural typing in Typescript and its benefits. By understanding structural typing in Typescript, you will have a better mental model of the type system and understand the behavior to expect from Typescript.
Thatβs it for today from me; If you liked this post, consider sharing it with your colleagues.
I hope you have a great week ahead and as always, keep on learning. Au Revoir ππ»!