TIL: October 2020
Tags: react, javascript, typescript, css
Published: 2020-10-08 22:52:44

### **Day 05 [Typescript/Redux] - How to type an dispatched action that returns a value with redux-thunk, react-hooks and typescript**

To get access to the returned value of a `ThunkAction` inside dispatch that don't pop any type errors you should declare the the type when initiate the dispatch.

```js
const dispatch = useDispatch<MyDispatchType>();
```

The generics define the retuned value of the `dispatch`, but the generic type should be of type `ThunkDispatch`.

`ThunkDispatch` receive 3 arguments, but to our case we just need to care about the first one, which is relative to the return type of the `dispatch`.

```js
type MyDispatchType = ThunkDispatch<MyType, any, AnyAction>
```
*__Obs:__ `ThunkDispatch` is exported from `redux-thunk` and `AnyAction` is exported from `redux`.*

With this, when you use the `dispatch` function it will provide autocomplete and a type-safe return based on `MyType`.

Full example:

```js
interface MyType {
  foo: number;
  bar: string;
  baz: string;
}

type MyDispatchType = ThunkDispatch<MyType, any, AnyAction>;

const myAction = (status: boolean) => (dispatch): MyType => {
  dispatch({ type: "foo", payload: { status } });
  return {
    foo: 23,
    bar: 'naruto',
    baz: 'hokage',
  }
}

function MyComponent() {
  const dispatch = useDispatch<MyDispatchType>();

  const handleClick = () => {
    //  No errors
    const { foo, bar, baz } = dispatch(myAction(true));
  }

  return (
    <button onClick={handleClick}>CLICK ME</button>
  )
}
```

### **Day 07 [Javascript] - How to return a value that is accessible only inside/after an event**

One of the gold questions of the Javascript past is now solved surprisingly easy, thanks to the `Promises`. 

So, imagine a scenario that your user add an audio file to an `input` and, before you upload the audio, for some reason, you need to get that audio duration. Before `Promises` it was impossible to achieve without bad practices or code smells since you only can get an audio duration after it was loaded, but with promises we can keep our code clean and do the trick.

As I found [here](https://stackoverflow.com/questions/34647536/how-to-get-audio-duration-value-by-a-function) promises could be used to return the value inside an event (which is pretty obvious BTW) so, on the case that we need to return the audio duration of a `File` when `onloadedmetadata` event is fired, we can do this:

```ts
  static async getAudioFileDuration(file: File): Promise<number> {
    return new Promise((resolve, reject) => {
      const objectUrl = URL.createObjectURL(file);
      const audio = new Audio(objectUrl);

      audio.onloadedmetadata = (e: any) => {
        resolve(audio.duration);
      };
    });
  }
```

The best of this approach is to avoid many work around on the web like have a *variable in the upper scopes of the methods*, *send a callback* or *do what you wanted to be outside of the event inside of it*. The `Promise` method keep the best practices, its modular, reusable and clean to read.

### **Day 12 [CSS] - How to `justify-self` with `flex`**

(Okay, I's embarrassing I did no know this before, BUT...)

I tried to answer [this StackOverFlow question](https://stackoverflow.com/questions/64175842/flexbox-boxes-inside-boxes/64175903#64175903) and realize (besides answering the question wrongly) I didn't know how to answer, what makes me think "Hey, I don't know the answer", and start to search.

The point is that for needing purposes, the property `justify-self` don't work on flex items because we can just use the `margin` proprty to reach the same behavior.

So, when need `justify-self: flex-end`, just replace this with `margin-left: auto`.

I create a [pen](https://codepen.io/alecell-the-lessful/pen/YzWZyoj) to exemplify this.

### **Day 15 [Typescript] - Why we have to reference dynamic types with the name of the type, and not only the type?**

Delving on the web these days I figure out a answer that I don't get that I have already: **Why we have to write dynamic keys like this:**

```ts
interface Foo {
  [key: string]: string;
} 
```

**instead of:**

```ts
interface Bar {
  [string]: string;
}
```

For too long I thought it was a typescript limitation, but I was wrong (maybe not btw), this exists for reading purposes, since name the `key` with something more clear is way more readable than just `key`.

```ts
interface Foo {
  [itemName: string]: string;
}
```

Now I'll stop to name the dynamic keys with just `key` and give them an appropriate name, and you should do it too. (if you don't do already of course)

### **Day 20 [Typescript] - Get the type of deeply nested dynamic key types**

Let's suppose we have a collection of objects like this:
```ts
interface Item {
  name: string;
  price: number;
}

interface ItemCollection {
  [itemId: string]: Item;
}
```

So we have a collection of `Items` that each one of the collection is its `itemId`.

Now, again, for some reason we need to get the type of `Item` by the collection, without reference the `Item` directly.

How can we get access to the type of each item of `ItemCollection`, to, let's say, create an type alias?

```ts
type TypeAlias = ItemCollection[string];
```

And that's it, is really easy to reference the type nested, you just need to use the type of the key as you would use the type reference directly, but not using the name, but the type itself.

### **Day 30 [Typescript/React] - Correctly type SVG to use as components**

For too long I wonder how to properly type SVG images when use ReactSvg or something like this, saddly I don't save the reference, but I found this:

```ts
  React.FC<React.SVGProps<SVGSVGElement>>;
```

So, when use it on the declarations, make something like this:

```ts
declare module '*.svg' {
  const content: React.FC<React.SVGProps<SVGSVGElement>>;
  export = content;
}
```