[Typescript] Step6: Types at Runtime

Step 5: Types at Runtime

This problem often happens when APi return the data.

let cachedAllTeamsList: Promise<ITeam[]>;
export async function getAllTeams(): Promise<ITeam[]> {
  if (typeof cachedAllTeamsList === 'undefined')
    cachedAllTeamsList = apiCall('teams');

  return await cachedAllTeamsList;
}

In this line of code: apiCall('teams');It is actually Promise<any>, and because we set cachedAllTeamsList: Promise<ITeam[]>, we cannot make sure whether there is any wired types going on.

 

Way to solve the problem is by: asserting and throw if the types we want is different.

function isITeam(arg: any): arg is ITeam {
  /**
   * {
  iconUrl: string;
  name: string;
  id: string;
  channels: IChannel[];
}
   */
  return (
    typeof arg.iconUrl === 'string' &&
    typeof arg.name === 'string' &&
    typeof arg.id === 'string' &&
    Array.isArray(arg.channels)
  );
}

function assertIsTypedArray<T>(
  arg: any,
  check: (val: any) => val is T,
): asserts arg is T[] {
  if (!Array.isArray(arg)) {
    throw new Error(`Not an array: ${JSON.stringify(arg)}`);
  }
  if (arg.some((item) => !check(item))) {
    throw new Error(`Violators found: ${JSON.stringify(arg)}`);
  }
}

let cachedAllTeamsList: Promise<ITeam[]>;
export async function getAllTeams(): Promise<ITeam[]> {
  if (typeof cachedAllTeamsList === 'undefined')
    cachedAllTeamsList = apiCall('teams').then((teams) => {
      assertIsTypedArray(teams, isITeam);
      return teams;
    });

  return await cachedAllTeamsList;
}

 

posted @ 2022-08-30 15:32  Zhentiw  阅读(21)  评论(0编辑  收藏  举报