掘金整理较全的地址:
https://juejin.cn/post/6844904182843965453#heading-42
gitbook:
https://jkchao.github.io/typescript-book-chinese

1. typeof 有什么作用?

使用 typeof 获取值所对应的类型

  1. var a = 1;
  2. type b = typeof a;

2. keyof 有什么作用?

获取类型中 Key 的联合类型

  1. var person = {
  2. name: 'alex',
  3. age: 30
  4. }
  5. type Person = keyof typeof person; //这里的 Person 为 'name' | 'age'
  6. interface IPerson {
  7. name: 'alex',
  8. age: 30
  9. }
  10. type KPerson = keyof Person; // 这里 KPerson 为 'name' | 'age'

3. TS 中类型保护的场景是什么?

在 ts 的条件块中如果出现 typeof,instanceof,in,字面量类型 的判断时,在 if 的代码块中会进行类型推断

当判断对象为普通对象,无法使用 typeof,instanceof 等判断时,可以自定义类型保护函数 isBar

  1. interface Bar {
  2. name: 'alex'
  3. }
  4. function isBar (val: any): val is Bar {
  5. return true;
  6. }
  7. function myName (val: any) {
  8. if (isBar(val)) {
  9. console.log(`my name is ${val.name}`)
  10. }
  11. }
  12. myName({ age: 30 })

4. 查看以下代码,说出 ret 是什么类型?

  1. function arrayToMap<T extends number> (arr: T[]): { [K in T]: K } {
  2. return arr.reduce((res, key) => res[key] = key, Object.create(null));
  3. }
  4. const ret = arrayToMap([1, 2, 3]);

ret 是一个对象类型,对象中的每一个属性为字面量类型

5. readonly 有哪些应用场景?

类属性,函数参数,类型属性,接口属性,或者是数组

  1. var aa: readonly number[] = [1, 2, 3];
  2. aa[0] = 4 //报错

6. 内置 API Readonly 的作用是什么?

把一个类型的所有属性都变成只读

  1. interface Person {
  2. name: string;
  3. age: number;
  4. }
  5. type ReadonlePerson = Readonly<Person>;

7. 自定义 Readonly 的实现?

  1. type Readonly<T extends object> = {
  2. readonly [K in keyof T]: T[K]
  3. }

这里有个疑问 🤔️:为什么用 interface 就报错呢?

  1. interface Readonly<T> {
  2. [K in keyof T]: T[K]
  3. }

8. 数组每项如何转为只读

  1. var a: ReadonlyArray<number> = [1, 2, 3];
  2. a[0] = 4; // 这里会报错,提示只读

自定义实现 ReadonlyArray

  1. type MyReadonlyArray<T> = readonly T[];
  2. type a = MyReadonlyArray<number>;
  3. // a 的类型为 readonly number[]

9. 使用泛型实现数组反转

  1. function reverse<T> (arr: T[]): T[] {
  2. let ret: T[] = [];
  3. arr.forEach(item => {
  4. ret.unshift(item)
  5. })
  6. return ret;
  7. }
  8. console.log(reverse([1, 2, 3]))
  9. console.log(reverse(['4', '5', '6']))
  10. console.log(reverse([Symbol(7), Symbol(8), Symbol(9)]))

10. 泛型约束是什么?

在使用泛型的过程中,泛型表示可随便传任何类型的值,所谓的约束即 extends string

  1. type OnlyString<T extends string> = {
  2. name: T
  3. }
  4. type a = OnlyString<string>

11. 使用泛型定义一个查询用户接口

  1. import axios, { AxiosResponse } from 'axios'
  2. interface Response<T> {
  3. code: number;
  4. message: string;
  5. body: T,
  6. state: number;
  7. }
  8. function getUser<T> (userId: string): Promise<AxiosResponse<Response<T>>> {
  9. return axios.get<Response<T>>('/user/' + userId)
  10. }
  11. interface User {
  12. name: string;
  13. age: number;
  14. }
  15. const promise = getUser<User>('123')
  16. promise.then(res => {
  17. res.data.body.name
  18. })

12. 怎么时候会走到 never 类型?

  1. 抛异常的函数,返回值为 never
  2. 不可能走到的分支代码

13. TS 如何判断两个类型是否相等?

只能通过判断类型 T 是否 extends 至类型 K,不能用于 === 判断

14. 如何从一个对象中提取出部分属性作为一个新类型

比如 Person 有 name 和 age,提取一个类型,只有 name 属性

  1. interface Person {
  2. name: string;
  3. age: number;
  4. school: string;
  5. }
  6. interface Man {
  7. name: string;
  8. age: number;
  9. }
  10. type MyName = Extract<keyof Person, keyof Man>
  11. type NameType = Pick<Person, MyName>

15. TS 如何进行详细的检查

比如像 ast 枚举词法时,如何保证词法穷举,可以使用一个走到会报错的方法来实现

  1. const _exhaustiveCheck: never = param;