DEV Community

Ruslan Shashkov
Ruslan Shashkov

Posted on

Some useful TypeScript snippets

Pick

If you need to construct a new type based on some properties of an interface you always can get the Pick utility type.

interface MyInterface {
  id: number;
  name: string;
  properties: string[];
}

type MyShortType = Pick<MyInterface, 'name' | 'id'>;
Enter fullscreen mode Exit fullscreen mode

Now MyShortType only have name and id properties extracted from MyInterface.

Omit

One more useful transformer type as Pick, but Omit works to "another direction" and excludes properties from the given interface. Let's have a look at the example:

interface MyInterface {
  id: number;
  name: string;
  properties: string[];
}

type MyShortType = Omit<MyInterface, 'name' | 'id'>;
Enter fullscreen mode Exit fullscreen mode

This time MyShortType only has properties property, because the others are omitted from MyInterface.

keyof

This is my favorite. Very useful for writing getters:

interface MyInterface {
  id: number;
  name: string;
  properties: string[];
}

const myObject: MyInterface = {
  id: 1,
  name: 'foo',
  properties: ['a', 'b', 'c']
};

function getValue(value: keyof MyInterface) {
  return myObject[value];
}

getValue('id'); // 1
getValue('count') // Throws compilation error: Argument of type '"count"' is not assignable to parameter of type '"id" | "name" | "properties"'.

Enter fullscreen mode Exit fullscreen mode

Record

If you tried to write types to a plain object like this, you know it looks like a mess then:

const myTypedObject: {[key: string]: MyInterface} = {
  first: {...},
  second: {...},
  ...
}
Enter fullscreen mode Exit fullscreen mode

Better to achieve this by using shiny Record type:

const myTypedObject: Record<string, MyInterface> = {
  first: {...},
  second: {...},
  ...
};

Enter fullscreen mode Exit fullscreen mode

That's a bit neater to use Record rather than ugly {[key: string]: ...} construction isn't it?

Bonus: Optional Chaining

This is a very useful feature. It is new in TypeScript since it released in 3.7. Almost every React Component has ugly code like this:

<React.Fragment>
  {apiResult && apiResult.data && apiResult.data.params && apiResult.data.params.showOnline && (<div>✅ Online</div>)}
</React.Fragment>
Enter fullscreen mode Exit fullscreen mode

Now you can do it like that (thanks to all the coding gods!):

<React.Fragment>
  {apiResult?.data?.params?.showOnline && (<div>✅ Online</div>)}
</React.Fragment>
Enter fullscreen mode Exit fullscreen mode

I hope these little snippets will help you a bit 🙃.

Discussion (2)

Collapse
egorovsa profile image
Sergey Egorov • Edited on

Great topic!!!

Some extras (:

  • you should remember that "?." feature is available since typescript v3.7

  • Record also let you describe available properties for an object, for instance:

interface AnimalInfo {
    name: string;
}

type Animal = 'cat' | 'dog' | 'mouse';

// Or use enum

// enum Anumal {
//   cat = 'cat',
//   dog = 'dog',
//   mouse = 'mouse' 
// }

const animals: Record<Animal, AnimalInfo> = {
  cat: { name: 'Jerry' },
  dog: { name: 'Spike' },
  mouse: {name: 'Tom'}
}
Collapse
pretaporter profile image
Maksim

Awesome!