前言
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 }
讯享网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 只是将 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"

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/21245.html