Home > Enterprise >  Typescript - Iterating through an Interface
Typescript - Iterating through an Interface

Time:10-27

I am a noob in working with typescript, but cannot avoid it in angular. So, I was writing the code as I learn.

I wanted to make a function that iterates over the keys of an object and performs some small tasks. In my case, I want to iterate through the keys because interface properties are optional and all of them may not be present. Here is the relevant part of my code: -

interface GameState {
  gameId?: string,
  minPlayers?: number,
  currentChoiceMakingPlayer?: number,
  gameEndReason?: string,
}

export class GameManagerService {

  gameState: GameState = {};

  synchroniseGameData = (gameState: GameState) => {
    for (let key in Object.keys(gameState)) {
      let typeKey = <keyof GameState>key;
      this.updateEntryInGameState(typeKey, gameState[typeKey]);
    }
  };

  updateEntryInGameState = <GameStateKey extends keyof GameState>(key: GameStateKey, value: GameState[GameStateKey]) => {
    this.gameState[key] = value;
  };
}

I understand most of it, except for the actual spotlight stealer function updateEntryInGameState (bottom of the code).

The tutorial I used gave this brief explanation (which I'll translate with respect to parameter names in my code): -

Adding the type variable GameStateKey for the key type allows us to use it for the value type while still ensuring that the key is a key of GameState using extends keyof GameState

But I still don't fully understand how this works.

Mainly, What does <GameStateKey extends keyof GameState> do before the function definition? And how is it being applied to the parameters of the function?

CodePudding user response:

What does <GameStateKey extends keyof GameState> do before the function definition?

It defines a generic type parameter for the arrow function being assigned to updateEntryInGameState.

And how is it being applied to the parameters of the function?

Wherever you see GameStateKey in the rest of the function's code, it gets its type from the type parameter. When you call updateEntryInGameState, the type of GameStateKey is inferred from the type of the first argument you give the function (the one received as the key parameter), and the second argument's type is then defined as the type of the property that that key designates in a GameState object (or subtype of it). (You can also specify the type explicitly as a type argument on the call, this.updateGameState<theTypeGoesHere>(/*...*/), but in this case there's no need.)

Basically, it lets you say that the key will be a key of GameState, and the value will be of the type of the property with that key in GameState. So during the call, if key is "gameId", the type of value will be string; if the key is "minPlayers", the type of value will be number.

  • Related