Typescript-关键词keyof和typeof的区别

455 阅读2分钟

Typescript-关键词keyof和typeof

keyoftypeof是TypeScript中两个常用的关键字,它们的作用不同。下面是它们的解释和使用场景的例子:

keyof

keyof是一个索引类型查询操作符,它用于获取一个类型的所有属性名组成的联合类型。例如,如果我们有一个类型Person,它有nameage两个属性:

type Person = {
  name: string;
  age: number;
};

使用keyof操作符,我们可以获取Person类型的所有属性名组成的联合类型:

type PersonKeys = keyof Person; // 'name' | 'age'

这个联合类型表示Person类型的所有可能的属性名。

使用场景:当我们需要对一个对象的属性名进行操作时,可以使用keyof操作符来获取属性名的联合类型,然后使用泛型约束来限制操作的属性名。

例如,我们可以定义一个函数,接收一个对象和一个属性名,返回该对象中该属性名对应的值:

function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

const person: Person = { name: 'Alice', age: 30 };
const name = getProperty(person, 'name'); // name: string
const age = getProperty(person, 'age'); // age: number
const invalidKey = getProperty(person, 'invalid'); // TypeScript编译错误:Argument of type 'string' is not assignable to parameter of type '"name" | "age"'

typeof

typeof是一个类型查询操作符,它用于获取一个值的类型。例如,如果我们有一个变量person,它的类型是Person

const person: Person = { name: 'Alice', age: 30 };

使用typeof操作符,我们可以获取person变量的类型:

type PersonType = typeof person; // Person

这个类型表示person变量的实际类型。

但是你如果直接打印看结果,是看不到类型Person的,这里再声明一个变量obj为例

// 这次让编译器类型推断而不是显式声明类型
const obj = {
  name: 'aa',
  age: 12
}

console.log(typeof obj)
console.log(typeof person); // 'object'

只能用鼠标移至变量名上你可以看到变量的类型结构

const obj: {  
name: string;  
age: number;  
}
// 显而易见的,使用typeof obj打印的结果肯定不会打印这么一长串

使用场景:当我们需要对一个变量的类型进行操作时,可以使用typeof操作符来获取变量的类型。

例如,我们可以定义一个函数,接收一个对象的构造函数,返回该对象的实例:

function createInstance<T>(ctor: new () => T): T {
  return new ctor();
}

class Person {
  name: string;
  age: number;
}

const person = createInstance(Person); // person: Person

在这个例子中,我们使用new () => T来表示一个构造函数类型,然后使用typeof操作符来获取Person类的构造函数类型,作为createInstance函数的参数类型。这样,我们就可以在createInstance函数内部使用new ctor()来创建Person类的实例了。