TypeScript typeof操作符

typeof 类型操作符

JavaScript本身就有typeof操作符,你可以在表达式上下文中使用:

console.log(typeof 'hello'); // print 'string'

而TypeScript添加的typeof方法可以在类型上下文中使用,用于获取一个变量或者属性的类型。

let s = 'hello';
let n: typeof s; // let n: string

如果仅仅用来判断基本的类型,那自然是没什么太大用,和其他的类型操作符搭配使用才能发挥它的作用。 举个例子:比如搭配TypeScript内置的ReturnType<T>。传入一个函数类型,ReturnType<T>会返回该函数返回值的类型。

type Fn = (x: unknown) => boolean;
type K = ReturnType<Fn>; //type K = boolean

如果我们对一个函数名使用ReturnType<T>,会收到这样一条报错:

function fn(x: unknown):boolean {
  return true;
}

type K = ReturnType<fn>; // 报错:“fn”表示值,但在此处用作类型。是否指“类型 fn”?

这是因为values(值)和types(类型)并不是一种东西,为了获取fn的类型,我们可以用到typeof

function fn(x: unknown):boolean {
  return true;
}

type K = ReturnType<typeof fn>; // type K = boolean

限制

TypeScript有意的限制了可以使用typeof的表达式的种类。 在TypeScript中,只有对标识符(比如变量名)或者他们的属性使用typeof才是合法的。这可能会导致一些令人迷惑的问题:

function msgBox(str: string): string {
  return str
}

let fn: typeof msgBox('hello'); // ',' expected.

我们本想获取函数返回值的类型,但其实上面的写法是不能正常执行的,原因就是因为typeof只能对属性或者标识符使用,而正确的写法应该是:

function msgBox(str: string): string {
  return str
}

let fn: ReturnType<typeof msgBox>; // let fn: string

对对象使用typeof

我们可以对一个对象使用typeof

let p = {
  name: 'zs',
  age: 18
}

type res = typeof p;
// type res = {
//   name: string;
//   age: number;
// }

对函数使用typeof

我们也可以对一个函数使用typeof

function fn<T>(x: T): T {
  return x
}
type res = typeof fn; // type res = <T>(x: T) => T

对枚举使用typeof

在TypeScript中,enum是一种新的数据类型,但在具体运行的时候,它会被编译成对象。

enum UserResponse {
  No = 0,
  Yes = 1,
}

对应编译的JavaScript代码为:

var UserResponse;
(function (UserResponse) {
    UserResponse[UserResponse["No"] = 0] = "No";
    UserResponse[UserResponse["Yes"] = 1] = "Yes";
})(UserResponse || (UserResponse = {}));

如果我们打印一下UserResponse

// log:{ '0': 'No', '1': 'Yes', No: 0, Yes: 1 }

如果我们对UserResponse使用typeof

enum UserResponse {
  No = 0,
  Yes = 1,
}
type n = typeof UserResponse

// n类型类似于
// {
//	"No": number,
//  "YES": number
// }

不过对一个enum类型只使用 typeof 一般没什么用,通常还会搭配 keyof 操作符用于获取属性名的联合字符串:

enum UserResponse {
  No = 0,
  Yes = 1,
}
type n = keyof typeof UserResponse; // type n = "No" | "Yes"