Typescript quick reference

When I started writing TypeScript, I didnā€™t have much of any experience with strongly-typed languages. For that reason, it was a bit of a sharp learning curve. Especially, when I was used to JS that just lets you do whatever the heck you want.

Today, I really love TS and Iā€™ve written a very basic intro that would have been helpful for me when I started. Hopefully, itā€™s helpful to someone else out there.

I love TS

Typing variables

This is generally pretty straightforward and easy to read:

// syntax is:
// const var_name: type = "value";
const thing: string = "asdf";
const otherThing: number = 3;

Note that these types are inline, meaning we set the type and declare the variable in the same line. You can also create the type then assign it to the variable, like this:

type Thing = string;

const thing: Thing = "asdf";

You wouldnā€™t probably do it this šŸ‘† way normally for a string, but when youā€™re making more complex types you certainly do. Letā€™s look at typing objects.

Typing objects

Typing objects is also fairly easy. The only thing here to be conscious of is properties are required unless you append the ? after the key. See aliases in the example:

type User = {
  name: string;
  email: string;
  score: number;
  aliases?: string[]; // optional array of strings; can be `undefined`.
  role: "reader" | "writer" | "admin"; // union
  favoriteColor?: string; // optional
}

Since I mentioned it above, you could define this type inline, but it starts to get cumbersome:

const user: {
  name: string;
  email: string;
  score: number;
  aliases?: string[]; // optional array of strings; can be `undefined`.
  role: "reader" | "writer" | "admin"; // union
  favoriteColor?: string; // optional
} = {
  name: "Pat",
  email: "pat@hotmail.com",
  score: 99,
  role: "writer",
  favoriteColor: "teal",
};
// ĀÆ\_(惄)_/ĀÆ

Typing functions

For some reason, this one was confusing to me initially. I think the reason it was confusing to me is that I was expecting there to be a type for a function. However, since all parts of the function should be typed (args and return value), to type a function itā€™s just a matter of syntax. You will use (args) => return type. Peep this:

// typing
type CapitalizeFunc = (text: string) => string;

// implementation
const capitalize: CapitalizeFunc = (text) => {
  return text[0].toUpperCase() + text.slice(1);
}

// or do it inline
const capitalize2 = (text: string): string => text[0].toUpperCase() + text.slice(1);

Above we use constants that have a value set to an anonymous function. One benefit of doing this is that it prevents the function from being redefined later on. It comes with a set of asterisks, though. Iā€™ll point you to a Google search for those.

If you prefer to write function() { ... } style functions, you can do so, but you canā€™t create a type to represent the whole function in the same way (that I know ofā€¦). You would do it like this:

function capitalize(text: string): string {
  return text[0].toUpperCase() + text.slice(1);
}

Utility types

There are bunch of utility types built in to Typescript. These include types that make all properties of an object required, no properties required, select some properties of an object, etc. The syntax on these can be a little confusing at first (it was to me). Here are a few examples to gain your bearings:

// type with optional props
type Favorites = {
  colors?: string[];
  flavors?: string[];
  numbers?: number[];
}

// now, a version with all required
// note that `Favorites` gets passed in to Required as an arg using the <...> syntax 
type FavoritesReq = Required<Favorites>;

// fyi, šŸ‘† is the same as šŸ‘‡
type FavoritesReq2 = {
  colors: string[];
  flavors: string[];
  numbers: number[];
}

You can do the opposite of what the Required type does with Partial. So, like this:

// this gets us back to where we started with the Favorites type
type FavoritesOpt = Partial<FavoritesReq>;

The final example Iā€™ll share is using the Pick type. This gives us the ability to create a new type with some of the properties from another type. So, letā€™s say we want favorites with only flavors and numbers:

type FavoritesLite = Pick<Favorites, "flavors" | "numbers">; // the second arg here is a union of the keys we want

Check out all the built-in utility types here: Typescript Utility Types. (If you just šŸ˜ lurve šŸ˜ these and want more utility types, check out type-fest šŸŽ‰.)

Type Generics

This is sort of an advanced topic, but I think itā€™s quite helpful to have some awareness of this early on. Typescript has ā€œgenericsā€ which are types that receive an argument and use the type of the argument in the resulting type.

For our first example, letā€™s say you have a function that wraps a value in an object, keeping the typing, and returns it (not necessarily a common use case, but itā€™s easy for an example). We can maintain the typing using generics. Consider the following:

// Note how we precede the function args with the type args <...>(...) => ...
const wrapIt = <T>(incoming: T): { wrapped: T } => ({
  wrapped: incoming,
});

The above example will let T be any type. We can narrow what T can be by extending existing types. Like this:

// T can only be a string, number, or boolean
const wrapIt = <T extends string | number | boolean>(incoming: T): { wrapped: T } => ({
  wrapped: incoming,
});

// Or, to make things easier to read as the type maybe grows with more props
// we can break this out into a type then an implementation
type WrapperFunc = <T extends string | number | boolean>(incoming: T) => { wrapped: T };

const wrapIt: WrapperFunc = (incoming) => ({
  wrapped: incoming,
});

Thereā€™s a lot more to generics and things can get a lot more complex, but this at least gives some intro that can be helpful as youā€™re thinking of typing your projects.

Definitely, check out the Typescript docs on Generics for a lot more details.


Thatā€™s it. Hope you like it.

Live, laugh, learn ā¤ļø.