前言
文中内容都是参考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 只是将 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.org/play 上运行过,版本为4.7.2。
最后, 如有错误,欢迎各位大佬指点!感谢!
参考资料
https://www.typescriptlang.org/docs/handbook/2/typeof-types.html
https://github.com/mqyqingfeng/Blog/issues/224
今天的文章typescript 类类型_基础的种类[通俗易懂]分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/86106.html