DEV Community

Cover image for Discoveries I made while using Typescript and React

Discoveries I made while using Typescript and React

adro.codes on June 02, 2019

Image credit @ellladee This week I have been working on a React app using Typescript and I've made a few discoveries that were very useful. This...
Collapse
 
theodesp profile image
Theofanis Despoudis

Some tips:

  • It's better if you avoid extends and just use union types:
interface IProps  {
  theme: Theme;
}

type CustomInputProps = HTMLAttributes<HTMLInputElement> & IProps;
  • Only allow specific keys on an object: You are actually describing the Record type
type TListenerTypes = "onload" | "progress" | "error"

const x: Record<TListenerTypes, Function> = {
    a: "something", // wrong type
    progress: () => {},
    d: 10 // wrong type
};

Collapse
 
g1itcher profile image
G1itcher

Regarding avoiding extends and just using union types: this is the kind of statement that definitely should be explained/quantified. Very easy for a beginner to see a comment like this and take it the wrong way.

Collapse
 
hurricaneinteractive profile image
adro.codes

The Record type is really cool! Definitely going to add that into the article. I'll have a look into the union types a bit, looks promising!

Collapse
 
ybogomolov profile image
Yuriy Bogomolov • Edited

Some more tips:

  1. Avoid using any at all costs! You will benefit from specifying types more precisely, and if you happen not to know the exact type, you can use unknown type – which is similar to any, but it doesn't allow code to escape the TypeScript type system. More on that: stackoverflow.com/questions/514398...

  2. Never-ever use Function and object types. It's the same thing as with any: you lose all type safety this way. For your example it's better to use React.EventHandler<T> type and its specializations like MouseEventHandler, PointerEventHandler and so on, or specify function signatures explicitly:

type TListenerTypes = 'onload' | 'progress' | 'error';
type TListeners = Record<TListenerTypes, React.MouseEventHandler>;

// or:

type TListeners = Record<TListenerTypes, ((e: Event) => void)>;

If you want to dive deeper in type-safe TypeScript development, please check out my article (it's currently on Medium, but if an interest arise, I'll re-post it here): levelup.gitconnected.com/typesafe-...

Collapse
 
arvigeus profile image
Nikolay Stoynov

Prefer using HTMLProps over HTMLAttributes:
stackoverflow.com/questions/481981...

Collapse
 
hurricaneinteractive profile image
adro.codes

Thanks for the advice!