Typing transformations in TypeScript
Typing transformations in TypeScript
I really enjoy using TypeScript and use it in all of my own projects. There's just something about knowing what types your objects and functions are, and the great code completion in VSCode, that I always miss when working on a JavaScript project.
One big annoyance for me is when I have a certain type of an object and I want to create a copy of that type where some fields have a different type.
I run into this a lot when receiving a type from a third-party library or an API request and I want to process and transform this object to make it easier to work with. As an example, consider an API endpoint that returns this type:
type ApiReponse = {
foo: number;
bar: string;
veryBigNumber: string; // overflows JS Number type, so it's encoded as a string by the API endpoint
date: string; // as ISOString "2020-05-30T11:39:40.230Z"
}
In my code I want to work with a JavaScript Date object instead of an ISOString, so in my API fetch function I do this transformation:
type TransformedApiReponse = ?
const request = async ():Promise<TransformedApiReponse[]> => {
const result = await fetch<ApiReponse[]>(url)
return result.map(response => ({
...response,
veryBigNumber: new BigNumber(response.veryBigNumber),
date: new Date(response.date),
}))
}
While TypeScript allows you to easily extend an object type using the & { newKey: string; } construct, it's hard to change an existing type.
Or so I thougt.
I used to copy and paste the existing ApiRepsonse type and then change the date field. However, if the type comes from a third-party library that's not possible and there's an easier much better way using omit, one of TypeScript's utility types:
// before
type TransformedApiReponse = {
foo: number;
bar: string;
veryBigNumber: BigNumber; // changed
date: Date; // changed
}
// now
type TransformedApiReponse = Omit<ApiReponse, "date" | "veryBigNumber"> & {
veryBigNumber: BigNumber;
date: Date;
}
type New = Omit<ApiReponse,"date" | "veryBigNumber">
& {
veryBigNumber: BigNumber;
date: Date;
}
First, we use Omit to remove the date and veryBigNumber field from the ApiReponse type and then we extend the resulting type using the new type values.
This way, we only specify the change set for the type instead of the whole type, and if the API endpoint's response type changes we only need to update the original ApiReponse type.
Have a look at some of the other TypeScript utility types - they can be very useful.
These are the ones I use most often:
Omit, Pick, Partial, ReturnType
Originally published at https://cmichel.io/typing-transformations-in-type-script/
Leave Typing transformations in TypeScript to:
Read more #eos posts
Best Posts From cmichel
We have not curated any of cmichel's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From cmichel
- How I gamed EOS Defi projects and still got rekt
- Progress Report - September 2020
- How to install an old package version with brew
- Fixing C++ compilation bugs for the MacOS Catalina upgrade
- Progress Report - August 2020
- Progress Report - July 2020
- Obfuscating EOSIO smart contracts
- Progress Report - June 2020
- Progress Report - May 2020
- Typing transformations in TypeScript
- 8 EOSIO WASM intrinsics you might not have heard about
- EOSIO C++ IntelliSense in VSCode
- Testing EOSIO smart contracts with Hydra
- Progress Report - March 2020
- Progress Report - February 2020
- How to check if an EOS account has a smart contract
- Launching EOS Token Portfolio
- How to deploy a create-react-app with github-actions
- Progress Report - January 2020
- How to rollback to an older EOSIO.CDT version with brew