Discover and read the best of Twitter Threads about #TypeScriptTuesday

Most recents (2)

This #TypeScriptTuesday, we're going to take a look at #TypeScript's interfaces.
Interfaces are different from types and both have their strengths in different situations.
Let's take a look.
This is just some interface definition - again an example from the #redux types:
🧵👇 interface Action {<br />
  type: string;<br />
}
An interface can also extend another interface.
Not only that, but also some (but not all) types.

The rule of thumb here is: if the type is well-known and could be written as an interface, it can be extended. // extending multiple interfaces is possible<br />
  interface StringPayloadActionWithError extends Action, WithErrorAttribute {<br />
    payload: string;<br />
  }<br />
<br />
  /**<br />
   * This can be resolved to { type: string; payload: string }, which<br />
   * could be expressed as an interface, so it can be extended.<br />
   */<br />
  interface StringPayloadAction extends Omit<StringPayloadActionWithError, {
meta: number;
}" src="/images/1px.png" data-src="https://pbs.twimg.com/media/EPZFwGmWkAEwwKG.jpg">
Another feature or Interfaces are index signatures. Interfaces can be indexed only by string or number, not by union types. You need Mapped Types for that.
If you index by string and number, the value indexed by number has to be a subset of the value indexed by string. interface SomethingElse {<br />
  [key: string]: string | number;<br />
  [key: number]: number;<br />
}<br />
<br />
interface InvalidInterface {<br />
  [key: string]: string;<br />
  // Error: An index signature parameter type cannot be a union type. Consider using a mapped object type instead.ts(1337)<br />
  [key: // Error: Numeric index type 'number' is not assignable to string index type 'string'.ts(2413)
[key: number]: number;
}
" src="/images/1px.png" data-src="https://pbs.twimg.com/media/EPZFw8KWsAMbDJi.jpg">
Read 7 tweets
While last #TypeScriptTuesday we looked at #TypeScript Generics Basics, today we continue where we left off, by taking a closer look at type argument inference, pitfalls and workarounds. We will take a look at a simplified version of #redux-toolkit's `createAction` function.
🧵👇 interface PayloadAction<P, T = string> {<br />
  type: T;<br />
  payload: P;<br />
}<br />
<br />
type ActionCreator<P, T> = (payload: P) => PayloadAction<P, T>;<br />
<br />
function createAction<P, T = string>(type: T): ActionCreator<P, T> {<br />
  return (payload: P) => ({<br />
    type,<br />
    payload<br />
  });<br />
}
Here, we call this function three ways:

1. With explicit type arguments. Everything is fine.
2. With inferred type arguments. P cannot be inferred, because it does not relate to any method argument.
3. With one explicit type argument. But why is the second argument not inferred? function createAction<P, T = string>(type: T): ActionCreator<P, T> {<br />
  /* ... */<br />
}<br />
<br />
const type =
// ActionCreator
const incrementAction = createAction(type);

// ActionCreator
const actionCreator2 = createAction(type);

// ActionCreator
const actionCreator3 = createAction(type);" src="/images/1px.png" data-src="https://pbs.twimg.com/media/EOQ6FriXUAEYJDD.jpg">
This is because #TypeScript cannot mix explicit and inferred type arguments.
There is a PR for that at github.com/microsoft/Type…, but there is still discussion on what syntax to use.
Let's just assume that this is impossible and try to work around it.
Read 6 tweets

Related hashtags

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3.00/month or $30.00/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!