DEV Community

Discussion on: TypeScript is wasting my time

Collapse
 
paratron profile image
Christian Engel • Edited

I cursed a lot when I started to use typescript as well. I felt as if someone tied rocks to my hands when I was able to write perfectly working JS before.

Soon you will adapt and naturally write code that gets along easier with TS. This is not exactly a drawback. Maybe it gets less elegant here and there, but its mostly for the better, trust me. Where you are, I have been - where I am, you will be :D

I don't have time to go into every single of your examples, but at least the first two:

Object.keys(localStorage).forEach((key) => {
  store.commit('cache/init', {
    key,
    value: JSON.parse(localStorage.getItem(key)),
  });
});
Enter fullscreen mode Exit fullscreen mode

TSC does a lot of code checking but it has its limits. It does not know that when you call localStorage.getItem(key), the key HAS to be present because its derived from the current keys in localStorage. To mitigate this, you can give the TSC a hint that a given value WILL be there by adding an exclamation mark: JSON.parse(localStorage.getItem(key)!)

This is somewhat the same problem:

function formatNumber(value: number, lang: string = 'en') {
  const options = {
    notation: 'compact',
    maximumFractionDigits: 1,
  };
  const formatter = Intl.NumberFormat(lang, options);
  return formatter.format(value);
}
Enter fullscreen mode Exit fullscreen mode

TSC sees: "ah, he assigned a string here" and internally derives the type of "options" to {notation: string, maximumFractionDigits: number}. He is not exactly incorrect here. But string does not match the options wanted for NumberFormat. So what you need to do is:

function formatNumber(value: number, lang: string = 'en') {
  const options: {notation: "compact", maximumFractionDigits: number} = {
    notation: 'compact',
    maximumFractionDigits: 1,
  };
  const formatter = Intl.NumberFormat(lang, options);
  return formatter.format(value);
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gmartigny profile image
Guillaume Martigny

As stated 2 times, I know this is mostly due to a lack of knowledge. So thanks a lot for the encouragements. I'm fully aware that a project with 80K stars and 33K commits over 650 contributors is not a failure.

Also, thanks for the two advices. BTW, @ryands17 taught me that Intl.NumberFormatOptions is an existing type.

Collapse
 
lioness100 profile image
Lioness100 • Edited

An easier way to do this is

const options = {
  ...
} as const;
Enter fullscreen mode Exit fullscreen mode

The "const assertion" will concrete the value to "compact" instead of string

Edit: oops, someone already mentioned that, sorry.

Collapse
 
fellz profile image
Roman

You should specify that notation not just the string type but concrete type Intl.NumberFormatOptions['notation']

  function formatNumber(value: number, lang: string = 'en') {
  const options = {
    notation: 'compact' as Intl.NumberFormatOptions['notation'],
    maximumFractionDigits: 1,
  };
   const formatter = Intl.NumberFormat(lang, options);
   return formatter.format(value);
}
Enter fullscreen mode Exit fullscreen mode