前言

文中内容都是参考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';  // truetypeof 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) => Personlet 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 只是将 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 | 3enum Direction {Up = 1,Down,Left,Right,
}type Result = keyof typeof Direction;
// type Result = "Up" | "Down" | "Left" | "Right"

8. 对 const 断言字面量使用

let str1 = 'hello';
// let str1: stringtype T1 = typeof str;
// type T1 = stringlet 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.org/play 上运行过,版本为4.7.2。
最后, 如有错误,欢迎各位大佬指点!感谢!

参考资料

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

TypeScript基础之typeof 类型操作符相关推荐

  1. TypeScript基础入门 - 接口 - 可索引的类型

    转载地址 TypeScript基础入门 - 接口 - 可索引的类型 项目实践仓库 https://github.com/durban89/typescript_demo.git tag: 1.0.11 ...

  2. TypeScript 基础类型 1

    TypeScript 基础类型 自本节起,我们将开始接触 TypeScript 的类型系统,这也是 TypeScript 最为核心的部分. 本节介绍 TypeScript 中一些基础类型,有些特殊类型 ...

  3. TypeScript基础入门之高级类型的可辨识联合(Discriminated Unions)

    2019独角兽企业重金招聘Python工程师标准>>> 转发 TypeScript基础入门之高级类型的可辨识联合(Discriminated Unions) 高级类型 可辨识联合(D ...

  4. Typescript基础类型以及与Javascript对比

    TypeScript数据类型以及与JavaScript对比 文章目录 TypeScript数据类型以及与JavaScript对比 介绍 一.数据类型与基础数据类型 1.数据类型 2.基础数据类型 3. ...

  5. TypeScript 基础 建议收藏!

    1.TypeScript 简介 1.1.什么是 TypeScript TypeScript 不是一门全新的语言,TypeScript 是 JavaScript 的超集,它对 JavaScript 进行 ...

  6. typescript基础

    TypeScript 基础语法 TypeScript 程序由以下几个部分组成: 模块 函数 变量 语句和表达式 注释 第一个 TypeScript 程序 我们可以使用以下 TypeScript 程序来 ...

  7. TypeScript完全解读(26课时)_12.TypeScript完全解读-高级类型(1)

    12.TypeScript完全解读-高级类型(1) 高级类型中文网的地址:https://typescript.bootcss.com/advanced-types.html 创建新的测试文件 ind ...

  8. TypeScript基础入门 - 接口 - 继承接口

    转载地址 TypeScript基础入门 - 接口 - 继承接口 项目实践仓库 https://github.com/durban89/typescript_demo.git tag: 1.0.13 为 ...

  9. TypeScript基础入门 - 泛型 - 泛型类型

    2019独角兽企业重金招聘Python工程师标准>>> 转载 TypeScript基础入门 - 泛型 - 泛型类型 项目实践仓库 https://github.com/durban8 ...

最新文章

  1. 最受欢迎 Top 12 Python 开源框架,你都用过吗?
  2. 青龙羊毛——狸猫十堰
  3. 对GET/POST请求返回cookie中的键值对进行重新组合
  4. 点击别的地方隐藏下拉列表
  5. android webservices 返回多行多列数据,Pandas: 如何将一列中的文本拆分为多行?
  6. 51Nod --1133 不重叠的线段
  7. BASIC-1_蓝桥杯_闰年判断
  8. 两种方法用于检查传入的数字是否为整数
  9. vfp控制excel使用sort_使用Python根据索引合并Excel表
  10. 买一个二级计算机软件多少钱,计算机二级考试需要买课本吗
  11. linux创建分区_在Linux中创建分区-分步指南
  12. 在线Cron在线表达式生成器工具推荐【磁钉cron生成器】
  13. qt之QTcpSocket
  14. 什么是系统时钟?什么是时钟系统?时钟系统有什么作用?
  15. Linux防火墙关闭方法
  16. 基于yolov5+deepsort的智能售货机商品目标检测种类识别计数
  17. 微信域名防封浅谈之一
  18. If Slack But Ryver!
  19. Vue.config.js开发环境与生产环境配置
  20. 文献 | 你的狗狗是否也很擅长“察言观色”?

热门文章

  1. 【proteus】proteus界面介绍
  2. 无法安装64位版本的office_手机微信有两个版本,32位和64位,你的微信是多少位?...
  3. 端到端加密优缺点_网络通信中常见的数据加密技术探析
  4. 浅谈百度刘超指导HCI讲堂印象笔记
  5. BurpSuite下载、设置代理以及FoxyProxy设置
  6. 郑州分销系统开发|二级分销系统开发应该如何分佣?
  7. 8页面html作品源代码,Html源代码.doc
  8. 爬虫软件在我们网站数据采集中起什么作用
  9. 【专访间】数据堂共同创始人肖永红:大数据促进云落地
  10. python 生成动态库_Python 项目转.so动态库