keyof可操作对象/类/接口/基本类型
typeof只获取变量的类型,操作符的后面接的始终是一个变量,且需要运用到类型定义当中。

keyof的使用

操作接口

keyof 后面跟的是类型,操作符提取其属性的名称。

  1. interface Boy {
  2. name: string;
  3. age: number;
  4. weight: number;
  5. }
  6. type boyName = keyof Boy; //通过keyof提取接口Boy的属性名称 name | age | weight
  7. type boyNames = keyof Boy[]; // 提取的是数组的属性 length | push | remove | pop | concat ...
  8. const byn: boyName = 'name';
  9. const byns: boyNames = 'length';
  10. console.log(byn, byns);

操作类class

  1. // 除了操作interface,keyof也可以操作class
  2. class Person {
  3. name = 'John';
  4. age = 12;
  5. }
  6. const p: keyof Person = 'name';
  7. // const g: keyof Person = 'gender'; // 类型报错, 不能将类型“"gender"”分配给类型“keyof Person”
  8. console.log(p);

基本类型

  1. // keyof除了支持interface和class外,也支持基本类型
  2. type str = keyof string;
  3. type num = keyof number;
  4. type sym = keyof symbol;
  5. // str --> "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "charAt" | "charCodeAt" | "localeCompare" | "match" | ... 36 more ... | "replaceAll"
  6. const kof1: str = 'lastIndexOf';
  7. // num --> "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision"
  8. const kof2: num = 'toFixed';
  9. //sym --> "toString" | typeof Symbol.toPrimitive | typeof Symbol.toStringTag | "valueOf" | "description"
  10. const kof3: sym = 'toString';
  11. console.log(kof1, kof2, kof3);

keyof的实例运用

  1. // 使用keyof和范型,多定义的类型进行范型保护
  2. function prop<T extends object, U extends keyof T>(obj: T, key: U): T[U] {
  3. return obj[key];
  4. }
  5. interface IpropObj {
  6. id: number;
  7. desc: string;
  8. }
  9. const propObj: IpropObj = {
  10. id: 100,
  11. desc: 'this is a prop',
  12. };
  13. const po: number = prop(propObj, 'id');
  14. console.group(po);

prop函数用于获取某个对象中指定属性的属性值,使用keyof操作符限定属性的类型。
使用了 TypeScript 的泛型和泛型约束。首先定义了 T 类型并使用 extends 关键字约束该类型必须是 object 类型的子类型,然后使用 keyof 操作符获取 T 类型的所有键,其返回类型是联合类型,最后利用 extends 关键字约束 K 类型必须为 keyof T 联合类型的子类型。

typeof的使用

typeof 操作符用于获取变量的类型,该操作符后面跟的必须是变量,且运用到类型type/interface等类型定义中。

  1. type Man = {
  2. name: string;
  3. age: number;
  4. };
  5. const man: Man = {
  6. name: 'shen',
  7. age: 30,
  8. };
  9. // typeof 后边跟的是变量
  10. type typeM = typeof man;
  11. interface IM1 {
  12. man: typeof man;
  13. height: number;
  14. }
  15. const m1: typeM = {
  16. age: 12,
  17. name: 'shen',
  18. };
  19. const m2: IM1 = {
  20. man: {
  21. age: 12,
  22. name: 'shen',
  23. },
  24. height: 170,
  25. };
  26. console.log(m1, m2);

keyof和typeof结合使用

  1. const COLORS = {
  2. red: 'red',
  3. blue: 'blue',
  4. };
  5. // 首先通过typeof操作符获取color变量的类型,然后通过keyof操作符获取该类型的所有键,
  6. // 即字符串字面量联合类型 'red' | 'blue'
  7. type colors = keyof typeof COLORS;
  8. let c: colors = 'red';
  9. c = 'blue';
  10. // c = 'black'; 类型报错,c: "red" | "blue" 为两个类型
  11. console.log(c);