关于typescript:TypeScript基础之typeof-类型操作符

46次阅读

共计 4909 个字符,预计需要花费 13 分钟才能阅读完成。

前言

文中内容都是参考 https://www.typescriptlang.org/docs/handbook/2/typeof-types.html , 以及参考
TypeScript 之 Typeof Type Operator — mqyqingfeng 内容。

typeof 类型操作符

先来看看 JavaScript 中 typeof 的用法:
具体可参考 MDN typeof

typeof 操作符返回一个字符串,示意未经计算的操作数的类型。

类型 后果
Undefined “undefined”
Null “object”
Boolean “boolean”
Number “number”
BigInt(ECMAScript 2020 新增) “bigint”
String “string”
Symbol (ECMAScript 2015 新增) “symbol”
宿主对象(由 JS 环境提供) 取决于具体实现
Function 对象 “function”
其余任何对象 “object”
// Undefined
typeof undefined === 'undefined';   // true
typeof declaredButUndefinedVariable === 'undefined';  // true

typeof null === 'object'; // true 

TypeScript 中的 typeof 常见用处是在类型上下文中获取变量或者属性的类型,此外还能够配合 ReturnType 获取函数的返回值类型,以及配合 keyof 应用。
如:

1. 获取变量类型

function fn (x: string | number) {if (typeof x === 'string') {x.toFixed(2);       // Property 'toFixed' does not exist on type 'string'.
    return x.split('');  
  }  
  // ...
}

2. 获取对象的类型

interface IPerson {
  name: string;
  age: number;  
}
let person: IPerson = {
  name: 'xman',
  age: 18  
};
type Person = typeof person;

let p: Person = {
  name: 'zxx',
  age: 20  
}

以上代码中通过 typeof 获取到 person 对象的类型,之后咱们就能够应用 Person 类型。
对于嵌套对象也是一样:

const userInfo = {
  name: 'xman',
  age: 18,
  address: {
    provice: '湖北',
    city: '武汉'
  }  
}

type UserInfo = typeof userInfo;

此时 UserInfo 类型如下:

type UserInfo = {
  name: string;
  age: number;
  address: {
    provice: string;
    city: string;
  };
}  

对只读属性的数组:

let arr: readonly number[] = [1, 2, 3];

type Type = typeof arr;
// type Type = readonly number[]

let arr1: Type = [2, 100];
arr1.push(1);
// type Type = readonly number[]

3. 获取函数的类型

function add (x: number, y: number): number {return x + y;}
type Add = typeof add;

此时 Add 类型为

type Add = (x: number, y: number) => number

看下如果没有显式的形容函数返回类型,typeof 会不会显示出返回类型:

function fn(x: string | number) {if (typeof x === "string") {return x.split("");
  }
  return x;
}

type Fn = typeof fn;

此时 Fn 类型为:

type T = (x: string | number) => number | string[]

能够看出,返回类型都推断进去了。

4. 对 enum 应用 typeof

enum 是一种新的数据类型,但在具体运行的时候,它会被编译成对象

enum Direction {
  Up = 1,
  Down,
  Left,
  Right,
}

编译成 JS 后代码:

"use strict";
var Direction;
(function (Direction) {Direction[(Direction["Up"] = 1)] = "Up";
  Direction[(Direction["Down"] = 2)] = "Down";
  Direction[(Direction["Left"] = 3)] = "Left";
  Direction[(Direction["Right"] = 4)] = "Right";
})(Direction || (Direction = {}));

Direction值为:

{
  1: "Up",
  2: "Down",
  3: "Left",
  4: "Right",
  Up: 1,
  Down: 2,
  Left: 3,
  Right: 4,
};

对 Direction 应用 typeof

type Result = typeof Direction;

let res: Result = {
  Up: 2,
  Down: 4,
  Left: 6,
  Right: 8,
};

此时 Result 类型相似于:

{
  Up: number,
  Down: number,
  Left: number,
  Right: number,
}

5. 对class 应用 typeof

class Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

let PersonClass: typeof Person;
// let PersonClass: new (name: string, age: number) => Person

let person = new PersonClass("xman", 18);

应用 typeof Person,意思是取Person 类的类型,而不是实例的类型。或者更确切的说:获取 Person 标识符的类型,也就是构造函数的类型。这个类型蕴含了类的所有动态成员和构造函数。之后,咱们在 PersonClass 上应用 new,创立 PersonClass 的实例。

6. 配合 ReturnType 获取函数的返回值类型

ReturnType定义:

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

infer 在这里用于提取函数类型的返回值类型。ReturnType<T> 只是将 infer R 从参数地位挪动到返回值地位,因而此时 R 即是示意待推断的返回值类型。

应用:

type Predicate = (x: unknown) => boolean;
type K = ReturnType<Predicate>;
// type K = boolean

如果咱们间接对一个函数名应用 ReturnType,咱们会看到这样一个报错:

function f() {return { x: 10, y: 3};
}
type P = ReturnType<f>;
// 'f' refers to a value, but is being used as a type here.

这是因为值(values)和类型(types)并不是一种货色。为了获取值 f 也就是函数 f 的类型,咱们就须要应用 typeof

function f() {return { x: 10, y: 3};
}
type P = ReturnType<typeof f>;
// type P = {
//   x: number;
//   y: number;
// };

7. 配合 keyof 应用

在 TypeScript 中,typeof 操作符能够用来获取一个变量或对象的类型。而 keyof 操作符能够用于获取某种类型的所有键,其返回类型是联结类型。
联合在一起应用:

const obj = {
  name: "xman",
  age: 18,
};

let k1: keyof typeof obj;
// let k1: "name" | "age"


const obj = {
  1: 'one',
  2: 'two',
  3: 'three'
} 
type k1 = keyof typeof obj;
// typeof obj 的后果为 {
//   1: string;
//   2: string;
//   3: string;
// }
// type k1 = 1 | 2 | 3

enum Direction {
  Up = 1,
  Down,
  Left,
  Right,
}

type Result = keyof typeof Direction;
// type Result = "Up" | "Down" | "Left" | "Right"

8. 对 const 断言字面量应用

let str1 = 'hello';
// let str1: string

type T1 = typeof str;
// type T1 = string

let str2 = 'hello' as const;
// let str2 = 'hello' as const;

type T2 = typeof str2;
// type T2 = "hello"

数组字面量利用 const 断言后,它将变成 readonly 元组,通过 typeof 操作符获取元组中元素值的联结类型

let arr1 = [1, 2, 3];
// let arr1: number[]

type T1 = typeof arr1;
// type T1 = number[]

let arr2 = [1, 2, 3] as const;
// let arr2: readonly [1, 2, 3]

type T2 = typeof arr2;
// type T2 = readonly [1, 2, 3]

对象字面量利用 const断言后,对象字面量的属性,将应用 readonly 润饰

let obj1 = {name: "xman", age: 18};
// let obj1: {
//   name: string;
//   age: number;
// };

type T1 = typeof obj1;
// type T1 = {
//   name: string;
//   age: number;
// };

let obj2 = {name: "xman", age: 18} as const;
// let obj2: {
//   readonly name: "xman";
//   readonly age: 18;
// };

type T2 = typeof obj2;
// type T2 = {
//   readonly name: "xman";
//   readonly age: 18;
// };

同样实用于蕴含援用类型的数组:

let arr1 = [{ name: "xman", age: 18},
  {name: "zxx", age: 22},
];
// let arr1: {
//   name: string;
//   age: number;
// }[];

type T1 = typeof arr1;
// type T1 = {
//   name: string;
//   age: number;
// }[];

let arr2 = [{ name: "xman", age: 18},
  {name: "zxx", age: 22},
] as const;
// let arr2: readonly [
//   {
//     readonly name: "xman";
//     readonly age: 18;
//   },
//   {
//     readonly name: "zxx";
//     readonly age: 22;
//   }
// ];

type T2 = typeof arr2;
// type T2 = readonly [
//   {
//     readonly name: "xman";
//     readonly age: 18;
//   },
//   {
//     readonly name: "zxx";
//     readonly age: 22;
//   }
// ];

type T3 = typeof arr2[number]['name'];
// type T3 = "xman" | "zxx"

以上 ts 代码均在 https://www.typescriptlang.or… 上运行过,版本为 4.7.2。
最初,如有谬误,欢送各位大佬指导!感激!

参考资料

https://www.typescriptlang.org/docs/handbook/2/typeof-types.html
https://github.com/mqyqingfeng/Blog/issues/224

正文完
 0