2025年TypeScript基础之typeof 类型操作符

TypeScript基础之typeof 类型操作符前言 文中内容都是参考 https www typescriptla 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 } 
讯享网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" 

参考资料

小讯
上一篇 2025-02-20 15:36
下一篇 2025-01-29 18:39

相关推荐

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