TypeScript基础之typeof 类型操作符
前言
文中内容都是参考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 类型操作符相关推荐
- TypeScript基础入门 - 接口 - 可索引的类型
转载地址 TypeScript基础入门 - 接口 - 可索引的类型 项目实践仓库 https://github.com/durban89/typescript_demo.git tag: 1.0.11 ...
- TypeScript 基础类型 1
TypeScript 基础类型 自本节起,我们将开始接触 TypeScript 的类型系统,这也是 TypeScript 最为核心的部分. 本节介绍 TypeScript 中一些基础类型,有些特殊类型 ...
- TypeScript基础入门之高级类型的可辨识联合(Discriminated Unions)
2019独角兽企业重金招聘Python工程师标准>>> 转发 TypeScript基础入门之高级类型的可辨识联合(Discriminated Unions) 高级类型 可辨识联合(D ...
- Typescript基础类型以及与Javascript对比
TypeScript数据类型以及与JavaScript对比 文章目录 TypeScript数据类型以及与JavaScript对比 介绍 一.数据类型与基础数据类型 1.数据类型 2.基础数据类型 3. ...
- TypeScript 基础 建议收藏!
1.TypeScript 简介 1.1.什么是 TypeScript TypeScript 不是一门全新的语言,TypeScript 是 JavaScript 的超集,它对 JavaScript 进行 ...
- typescript基础
TypeScript 基础语法 TypeScript 程序由以下几个部分组成: 模块 函数 变量 语句和表达式 注释 第一个 TypeScript 程序 我们可以使用以下 TypeScript 程序来 ...
- TypeScript完全解读(26课时)_12.TypeScript完全解读-高级类型(1)
12.TypeScript完全解读-高级类型(1) 高级类型中文网的地址:https://typescript.bootcss.com/advanced-types.html 创建新的测试文件 ind ...
- TypeScript基础入门 - 接口 - 继承接口
转载地址 TypeScript基础入门 - 接口 - 继承接口 项目实践仓库 https://github.com/durban89/typescript_demo.git tag: 1.0.13 为 ...
- TypeScript基础入门 - 泛型 - 泛型类型
2019独角兽企业重金招聘Python工程师标准>>> 转载 TypeScript基础入门 - 泛型 - 泛型类型 项目实践仓库 https://github.com/durban8 ...
最新文章
- 最受欢迎 Top 12 Python 开源框架,你都用过吗?
- 青龙羊毛——狸猫十堰
- 对GET/POST请求返回cookie中的键值对进行重新组合
- 点击别的地方隐藏下拉列表
- android webservices 返回多行多列数据,Pandas: 如何将一列中的文本拆分为多行?
- 51Nod --1133 不重叠的线段
- BASIC-1_蓝桥杯_闰年判断
- 两种方法用于检查传入的数字是否为整数
- vfp控制excel使用sort_使用Python根据索引合并Excel表
- 买一个二级计算机软件多少钱,计算机二级考试需要买课本吗
- linux创建分区_在Linux中创建分区-分步指南
- 在线Cron在线表达式生成器工具推荐【磁钉cron生成器】
- qt之QTcpSocket
- 什么是系统时钟?什么是时钟系统?时钟系统有什么作用?
- Linux防火墙关闭方法
- 基于yolov5+deepsort的智能售货机商品目标检测种类识别计数
- 微信域名防封浅谈之一
- If Slack But Ryver!
- Vue.config.js开发环境与生产环境配置
- 文献 | 你的狗狗是否也很擅长“察言观色”?
热门文章
- 【proteus】proteus界面介绍
- 无法安装64位版本的office_手机微信有两个版本,32位和64位,你的微信是多少位?...
- 端到端加密优缺点_网络通信中常见的数据加密技术探析
- 浅谈百度刘超指导HCI讲堂印象笔记
- BurpSuite下载、设置代理以及FoxyProxy设置
- 郑州分销系统开发|二级分销系统开发应该如何分佣?
- 8页面html作品源代码,Html源代码.doc
- 爬虫软件在我们网站数据采集中起什么作用
- 【专访间】数据堂共同创始人肖永红:大数据促进云落地
- python 生成动态库_Python 项目转.so动态库