拿6个案例讲解TypeScript 知识点( 二 )

解答本题考查联合类型的使用:
// 定义联合类型type Person = User | Adminconst persons: Person[] /* <- Person[] */ = [  {    name: "Max Mustermann",    age: 25,    occupation: "Chimney sweep",  },  {    name: "Jane Doe",    age: 32,    role: "Administrator",  },  {    name: "Kate Müller",    age: 23,    occupation: "Astronaut",  },  {    name: "Bruce Willis",    age: 64,    role: "World saver",  },]function logPerson(user: Person) {  console.log(` - ${chalk.green(user.name)}, ${user.age}`)}exercise-02根据上题中定义出的 Person 类型 , 现在需要一个方法打印出它的实例:
题目function logPerson(person: Person) {  let additionalInformation: string  if (person.role) {    // ? 报错 Person 类型中不一定有 role 属性    additionalInformation = person.role  } else {    // ? 报错 Person 类型中不一定有 occupation 属性    additionalInformation = person.occupation  }  console.log(    ` - ${chalk.green(person.name)}, ${person.age}, ${additionalInformation}`,  )}解答本题考查 TypeScript 中的「类型保护」 , TypeScript 的程序流分析使得某些判断代码包裹之下的代码中 , 类型可以被进一步收缩 。
in 操作符:
function logPerson(person: Person) {  let additionalInformation: string  if ("role" in person) {    additionalInformation = person.role  } else {    additionalInformation = person.occupation  }  console.log(    ` - ${chalk.green(person.name)}, ${person.age}, ${additionalInformation}`,  )}函数返回值中的 is 推断:
function isAdmin(user: Person): user is Admin {  return user.hasOwnProperty("role")}function logPerson(person: Person) {  let additionalInformation: string  if (isAdmin(person)) {    additionalInformation = person.role  } else {    additionalInformation = person.occupation  }  console.log(    ` - ${chalk.green(person.name)}, ${person.age}, ${additionalInformation}`,  )}exercise-04题目本题定义了一个 filterUsers 方法 , 用来通过 person 中的某些字段来筛选出用户的子集 。
function filterUsers(persons: Person[], criteria: User): User[] {  return persons.filter(isUser).filter((user) => {    let criteriaKeys = Object.keys(criteria) as (keyof User)[]    return criteriaKeys.every((fieldName) => {      return user[fieldName] === criteria[fieldName]    })  })}console.log(chalk.yellow("Users of age 23:"))filterUsers(  persons,  // ? 报错 , criteria 定义的是精确的 User 类型 , 少字段了 。  {    age: 23,  },).forEach(logPerson)可以看出 , 由于 filterUsers 的第二个筛选参数的类型被精确的定义为User , 所以只传入它的一部分字段 age 就会报错 。
解答本题考查 [mapped-types](
https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types "mapped-types") 映射类型 , 
type Criteria = {  [K in keyof User]?: User[K]}function filterUsers(persons: Person[], criteria: Criteria): User[] {  return persons.filter(isUser).filter((user) => {    let criteriaKeys = Object.keys(criteria) as (keyof User)[]    return criteriaKeys.every((fieldName) => {      return user[fieldName] === criteria[fieldName]    })  })}


推荐阅读