admin管理员组

文章数量:1597847

点击蓝色“脑洞前端”关注我哟

加个“星标”,带你揭开大前端的神秘面纱!

这是脑洞前端第「106」篇原创文章

TypeScript 的学习资料非常多,其中也不乏很多优秀的文章和教程。但是目前为止没有一个我特别满意的。原因有:

  • 它们大多数没有一个清晰的主线,而是按照 API 组织章节的,内容在「逻辑上」比较零散。

  • 大多是“讲是什么,怎么用“,而不是”讲为什么,讲原理“。

  • 大多数内容比较枯燥,趣味性比较低。都是干巴巴的文字,没有图片,缺乏能够引起强烈共鸣的例子。

因此我的想法是做一套不同市面上大多数的 TypeScript 学习教程。以人类认知的角度思考问题,学习 TypeScript,通过通俗易懂的例子和图片来帮助大家建立 TypeScript 世界观。

系列安排:

  • 上帝视角看 TypeScript

  • TypeScript 类型系统

  • types 和 @types 是什么?

  • 你不知道的 TypeScript 泛型(万字长文,建议收藏)

  • typeScript 配置文件该怎么写?

  • TypeScript 是如何与 React,Vue,Webpack 集成的?

  • TypeScript 练习题

目录将来可能会有所调整。

注意,我的系列文章基本不会讲 API,因此需要你有一定的 TypeScript 使用基础,推荐两个学习资料。

  • 深入理解 TypeScript[1]

  • TypeScript 官方文档[2]

结合这两个资料和我的系列教程,掌握 TypeScript 指日可待。

接下来,我们通过几个方面来从宏观的角度来看一下 TypeScript。

前言

本文涉及的题目一共十六道,全部都可以在 typescript-exercises[3] 上在线提交。

可以和标准答案进行对比。

并且由于使用了浏览器缓存, 因此无需登录的情况下也可以保证关掉页面,你的答题进度也会保留。

想重置进度,清空缓存,无痕模式或者换浏览器都可以。

题目中涉及到的知识点我基本也都在之前的文章中提到了,如果你没有看过,强烈建议先完成前面的教程,然后将上面的题目自己做一遍之后再看本文。另外一定要按照顺序读, 因此前面的题目都是后面的铺垫。

为了不让文章太过于冗长, 本篇文章分两次发布, 一次 8 道题,一共十五道。每道题都有思路,前置知识以及代码。「这次给大家带来的是后 6 道」

其中有一道题需要大家有函数式编程的知识, 如果大家不知道会比较难以解释。为了避免内容太过分散,将这道题从我的题解中移除,故只有 6 道。

题目九

题目描述

Intro:

    PowerUsers idea was bad. Once those users got
    extended permissions, they started bullying others
    and we lost a lot of great users.
    As a response we spent all the remaining money
    on the marketing and got even more users.
    We need to start preparing to move everything to a
    real database. For now we just do some mocks.

    The server API format was decided to be the following:

    In case of success: { status: 'success', data: RESPONSE_DATA }
    In case of error: { status: 'error', error: ERROR_MESSAGE }

    The API engineer started creating types for this API and
    quickly figured out that the amount of types needed to be
    created is too big.

Exercise:

    Remove UsersApiResponse and AdminsApiResponse types
    and use generic type ApiResponse in order to specify API
    response formats for each of the functions.

题目的大概意思是:之前都是写死的数据, 现在数据需要从接口拿,请你定义这个接口的类型。

题目内置代码

interface User {
  type: "user";
  name: string;
  age: number;
  occupation: string;
}

interface Admin {
  type: "admin";
  name: string;
  age: number;
  role: string;
}

type Person = User | Admin;

const admins: Admin[] = [
  { type: "admin", name: "Jane Doe", age: 32, role: "Administrator" },
  { type: "admin", name: "Bruce Willis", age: 64, role: "World saver" },
];

const users: User[] = [
  {
    type: "user",
    name: "Max Mustermann",
    age: 25,
    occupation: "Chimney sweep",
  },
  { type: "user", name: "Kate Müller", age: 23, occupation: "Astronaut" },
];

export type ApiResponse<T> = unknown;

type AdminsApiResponse =
  | {
      status: "success";
      data: Admin[];
    }
  | {
      status: "error";
      error: string;
    };

export function requestAdmins(callback: (response: AdminsApiResponse) => void) {
  callback({
    status: "success",
    data: admins,
  });
}

type UsersApiResponse =
  | {
      status: "success";
      data: User[];
    }
  | {
      status: "error";
      error: string;
    };

export function requestUsers(callback: (response: UsersApiResponse) => void) {
  callback({
    status: "success",
    data: users,
  });
}

export function requestCurrentServerTime(
  callback: (response: unknown) => void
) {
  callback({
    status: "success",
    data: Date.now(),
  });
}

export function requestCoffeeMachineQueueLength(
  callback: (response: unknown) => void
) {
  callback({
    status: "error",
    error: "Numeric value has exceeded Number.MAX_SAFE_INTEGER.",
  });
}

function logPerson(person: Person) {
  console.log(
    ` - ${person.name}, ${person.age}, ${
      person.type === "admin" ? person.role : person.occupation
    }`
  );
}

function startTheApp(callback: (error: Error | null) => void) {
  requestAdmins((adminsResponse) => {
    console.log("Admins:");
    if (adminsResponse.status === "success") {
      adminsResponse.data.forEach(logPerson);
    } else {
      return callback(new Error(adminsResponse.error));
    }

    console.log();

    requestUsers((usersResponse) => {
      console.log("Users:");
      if (usersResponse.status === "success") {
        usersResponse.data.forEach(logPerson);
      } else {
        return callback(new Error(usersResponse.error));
      }

      console.log();

      requestCurrentServerTime((serverTimeResponse) => {
        console.log("Server time:");
        if (serverTimeResponse.status === "success") {
          console.log(
            `   ${new Date(serverTimeResponse.data).toLocaleString()}`
          );
        } else {
          return callback(new Error(serverTimeResponse.error));
        }

        console.log();

        requestCoffeeMachineQueueLength((coffeeMachineQueueLengthResponse) => {
          console.log("Coffee machine queue length:");

本文标签: 练习题typescript