[月分享] TypeScript - 常用内置类型与使用技巧


/**
 * keyof<T>
 *  获取一个对象接口的所有 key 值
 *  keyof 与 Object.keys 略有相似,只不过 keyof 取 interface 的键。
 */
() => {
  interface Person {
    name: string;
    age: number;
    location: string;
  }

  type K1 = keyof Person; // "name" | "age" | "location"
  type K2 = keyof Person[]; // "length" | "push" | "pop" | "concat" | ...
  type K3 = keyof { [x: string]: Person }; // string

  // 获取对象的属性
  function pluck<T, K extends keyof T>(o: T, names: K): T[K] {
    return o[names];
  }
};
(_tip: "keyof 只会返回不为 null undefined never 的类型") => {
  interface EnumType {
    a: never;
    b: undefined;
    c: null;
    d: number;
    e: object;
  }
  type TypeEnumType = keyof EnumType; // a | b | c | d | e
  type TypeEnumType1 = EnumType[keyof EnumType]; // number | object 去除了了3种假类型

  type ReadonlyType<T> = {
    readonly [P in keyof T]?: T[P];
  };
  let readOnly: ReadonlyType<EnumType> = {}; // 将 EnumType 所有类型都变为了了 只读
};

/**
 * Pick<T, K>
 *  从对象类型 T 挑选一些属性 K
 *  比如对象拥有 5 个 key,只需要将 K 设置为 "name" | "age" 就可以生成仅支持这两个 key 的新对象类型。
 */
() => {
  interface IObj {
    a: string;
    b: number;
    c: boolean;
  }
  type FilterObj = Pick<IObj, "a" | "b">;
  const test: FilterObj = {
    a: "str",
    b: 1,
  };
};

/**
 * Extract<T, U>
 *  挑选 key 中的 key
 *  Extract 是 Pick 的底层 API,直到 2.8 版本才内置进来,
 *  可以认为 Pick 是挑选对象的某些 key,Extract 是挑选 key 中的 key。
 */
() => {
  interface IObj {
    a: string;
    b: number;
    c: boolean;
  }
  type FilterKey = Extract<keyof IObj, "a">;
  const test: FilterKey = "a";
};

/**
 * Exclude<T, U>
 *  将 T 中的 U 类型排除,和 Extract 功能相反。
 */
() => {
  interface IObj {
    a: string;
    b: number;
    c: boolean;
  }
  type FilterKey = Exclude<keyof IObj, "a" | "b">;
  const test: FilterKey = "c";
};

/**
 * Record<K, U>
 *  将 K 中所有的属性的值转化为 U 类型
 *  ts文档上对Record的介绍不多,但却经常用到,Record是一个很好用的工具类型。
 *  他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型
 */
(_tip: "源码") => {
  // 将K中的所有属性值都转换为T类型,并将返回的新类型返回给proxyKType,K可以是联合类型、对象、枚举
  type Record<K extends keyof any, T> = {
    [P in K]: T;
  };
};
(_tip: "Demo") => {
  interface AnimalsInfo {
    dog: {
      name: string;
      age: number;
    };
    cat: {
      name: string;
      age: number;
    };
  }
  const animalsInfo: AnimalsInfo = {
    dog: {
      name: "dogName",
      age: 2,
    },
    cat: {
      name: "catName",
      age: 3,
    },
  };
};
(_tip: "Demo1") => {
  type petsGroup = "dog" | "cat";
  interface IPetInfo {
    name: string;
    age: number;
  }
  type IPets = Record<petsGroup, IPetInfo>;
  const animalsInfo = {
    dog: {
      name: "dogName",
      age: 2,
    },
    cat: {
      name: "catName",
      age: 3,
    },
  };
};
(_tip: "Demo2") => {
  type petsGroup = "dog" | "cat";
  interface IPetInfo {
    name: string;
    age: number;
  }
  type IPets = Record<petsGroup | "otherAnamial", IPetInfo>;
  const animalsInfo: IPets = {
    dog: {
      name: "dogName",
      age: 2,
    },
    cat: {
      name: "catName",
      age: 3,
    },
    otherAnamial: {
      name: "otherAnamialName",
      age: 10,
    },
  };
};

/**
 * Omit<K, U>
 *  返回移除 K 对象中的 U 属性后的新类型
 */

(_tip: "源码") => {
  type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
};
(_tip: "使用") => {
  type Foo = Omit<{name: string, age: number}, 'name'> // { age: number }
};


/**
 * 技巧
 *  数组类型明文确认长度
 */
before => {
  const data = [
    [1, 5.5],
    [2, 3.7],
    [3, 2.0],
    [4, 5.9],
    [5, 3.9],
  ];
};
after => {
  interface CharData extends Array<number> {
    0: number;
    1: number;
    length: 2;
  }
  const data2: CharData[] = [
    [1, 5.5],
    [2, 3.7],
    [3, 2.0],
    [4, 5.9],
    [5, 3.9],
  ];
};
(ts 3.0+) => {
  type Tuple<TItem, TLength extends number> = [TItem, ...TItem[]] & {
    length: TLength;
  };
  const data3: Tuple<number,2>[] = [
      [1, 5.5],
      [2, 3.7],
      [3, 2.0],
      [4, 5.9],
      [5, 3.9],
    ];
  tips: ts 3.0在元组类型中引入了其余元素
  // https://stackoverflow.com/questions/52489261/typescript-can-i-define-an-n-length-tuple-type
}

/**
 * 技巧
 *  巧用查找类型
 */
before => {
  interface Person {
    addr: {
      city: string;
      street: string;
      num: number;
    };
  }
  interface Address {
    city: string;
    street: string;
    num: number;
  }
  const Addr: Address = {
    city: "city",
    street: "street",
    num: 0,
  };
};
after => {
  interface Person {
    addr: {
      city: string;
      street: string;
      num: number;
    };
  }
  const Addr: Person["addr"] = {
    city: "city",
    street: "street",
    num: 0,
  };
};

/**
 * 技巧
 *  找到 Object rest 类型
 */
//
before => {
  interface XYZ {
    x: number;
    y: number;
    z: number;
  }
  const restObj: XYZ = { x: 1, y: 2, z: 3 };
  const { x, y, z, ...rest } = restObj;
  function dropXYZ(restObj: XYZ, ...rest) {
    return rest;
  }
};
// after (Pick , Exclude)
after => {
  interface XYZ {
    x: number;
    y: number;
    z: number;
  }

  type DropXYZ<T> = Pick<T, Exclude<keyof T, keyof XYZ>>;

  function _dropXYZ<T extends XYZ>(
    restObj: XYZ,
    ...rest: Array<DropXYZ<T>>
  ): Array<DropXYZ<T>> {
    return rest;
  }
};



结束了?

...

还有个小彩蛋~

这里有个关于 Promise 的小题目:


  const p1 = new Promise((resolve,reject) => {
    console.log('Promise 1');
    resolve();
  }).then(() => {
    console.log('then 11');
    const p2 = new Promise((resolve,reject) => {
      console.log('Promise 2');
      resolve();
    }).then(() => {
      console.log('then 21');
    }).then(() => {
      console.log('then 22');
    })
  }).then(() => {
    console.log('then 12')
  })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

  • 为了便于后期维护,本人在 Github 上新建了一个 awesome-typescript 项目,欢迎大家分享新的...
    semlinker阅读 11,474评论 0 65
  • 很多时候虽然我们了解了TypeScript相关的基础知识,但是这不足以保证我们在实际项目中可以灵活运用,比如现在绝...
    java成功之路阅读 8,846评论 0 1
  • 歌词/孟文豪 斩情思三千 断不了思念 剪相思红线 却愈发留恋 写情诗三千 换不回红颜 画丹青美眷 却背影渐远 你的...
    馨晴百合阅读 4,916评论 1 10
  • 《等你一起出发》 ——文/飞雪 我慢慢等你长大 不怕岁月将我变老 我等你一起出发 走过山山水水 大手拉着小手 路在...
    洛阳牡丹文化诗社阅读 2,812评论 0 0
  • Servlet 是什么?Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 We...
    逆风飞行1226阅读 1,549评论 0 1

友情链接更多精彩内容