TypeScript从类型创建类型之Keyof,typeof操作符

48 阅读2分钟

keyof类型操作符

keyof操作符的作用就是用对象类型生成字符串数字联合类型。下面的类型P"x"|"y"是一样的 :

type Point = { x: number; y: number };
type P = keyof Point;

如果类型有string或者number 的索引签名,keyof操作符会返回索引签名的类型:

type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish;
    
type A = number
 
type Mapish = { [k: string]: boolean };
type M = keyof Mapish;
     // type M = string | number

请注意在上面这个例子当中,Mstring | number类型----这是因为JavaScript的键会被转换成string类型,所以obj[0]obj["0"]是一样的。

typeof操作符

JavaScript已经有一个typeof了:

// Prints "string"
console.log(typeof "Hello world");

TypeScript添加了一个可以用在类型上下文上来引用一个变量或者属性的类型的typeof操作符:

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

对于基础类型来说这并不是非常有用,但是和其它类型运算符进行结合使用的时候,typeof可以方便的表现多种形式。举个列子,让我们从查看预定义类型ReturnType<T>开始。ReturnType返回函数返回类型

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

尝试用函数名,我们会得到一个错误

function f() {
  return { x: 10, y: 3 };
}
type P = ReturnType<f>;
// 'f' refers to a value, but is being used as a type here. Did you mean 'typeof f'?

请记住类型不是同一种东西。为了引用值的类型,我们用typeof

function f() {
  return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
    //type P = {
      x: number;
      y: number;
     }

限制

TypeScript有意限制使用typeof。 具体来说,仅对标识符(即变量名)或其属性使用tyoeof是合法的:

// Meant to use = ReturnType<typeof msgbox>
let shouldContinue: typeof msgbox("Are you sure you want to continue?")
// ',' expected.

翻译自
TypeScript: Documentation - Keyof Type Operator (typescriptlang.org)
TypeScript: Documentation - Typeof Type Operator (typescriptlang.org)