Creating Custom Types in TypeScript
Let's look at how to create custom types in TypeScript
Join the DZone community and get the full member experience.
Join For FreeJavaScript is a weakly typed language, which means we don't usually think about types. Typescript is strongly typed, which means everything has a type.
Occasionally we want to make an object or the return of a function conform to a certain format. This is where we use custom types. Typescript allows us to define our own custom types, which we can then use in our code.
Why Would We Use Custom Types?
Suppose you have a function that always returns data in a certain format, and uses an API to get that data. If the API returns data in the wrong format, we probably don't want the wrongly formatted data to end up in our code where it could cause issues. In such a case, we might ask that the return of a function conforms to a certain type. As such, we would define our own type.
Alias Types
One example of how to create types is called an alias type. An example of how we define a type is shown below:
type Company = {
name: string,
address: string,
value?: number
}
If we give something the type Company, then we expect it to have at least a name and address, and an optional value, which does not have to be given. As you can see, having a question mark in our type denotes that this property is optional.
If we were to use this in code, we might do something like this:
let myFunction = async function(): Promise<Company> {
let getApi = await fetch('/myApi/data', {
method: 'GET'
})
let getResult:Company = await getApi.json();
return getResult;
}
In the above code, we are returning a Promise of type Company, and if we don't get that, we'll get an error. So for example, if we try to run this and we don't get an address or name back from our API, we will have an error that we can handle.
Extending Alias Types
You can extend alias types, i.e. if you want to add a new element to it. For example:
type Company = {
name: string,
address: string,
value?: number
}
type SubCompany = Company & {
identity: string
}
In the above, SubCompany will have everything Company has, plus a required attribute called identity.
Using Interfaces instead
Everything we've spoken about so far has been using the type keyword, but we can do the same stuff using the interface keyword instead. It is really personal preference which one you use. Our example above looks like this with interface:
interface Company {
name: string,
address: string,
value?: number
}
interface SubCompany extends interface {
identity: string
}
Union Types
We can also define custom types using a much simpler syntax known as union types. Let's say we have a type which is either going to be a string or number, called myType. We could define that type as shown below:
type myType = number | string
Literal Types
This is where we set a type that has a specific list of values it can select from. Let's say our original type, Company, can only have three values, red, blue, or green. We can define a literal type, and use that as the type of our name attribute:
type Option = "blue" | "green" | "red"
type Company = {
name: Option,
address: string,
value?: number
}
Published at DZone with permission of Johnny Simpson, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments