TS中typeof和keyof

字面量类型

在了解typeof和keyof之前,我们首先需要了解什么是字面量类型以及联合字面量类型。
TypeScript 中的字面量类型是更具体的string、number或boolean类型,它可以被这样定义:

type Greeting = 'hello';

这意味着类型为Greeting的变量只能有一个字符串值’hello’:

const foo: Greeting = 'hello';
const bar: Greeting = 'world'; // Type '"world"' is not assignable to type '"hello"'.ts(2322)

字面量类型本身可能并不是很实用,但是它可以和联合类型一起组合出强大的抽象,也就是我们说的联合字面量类型:

type Greeting = 'hello' | 'world';

const foo: Greeting = 'hello';
const bar: Greeting = 'world';

typeof

如果对象是一个嵌套的对象,typeof也能够正确获取到它们的类型。

const p = {
  name: 'CJ',
  age: 18,
  address: {
    city: 'SH'
  }
};

//typeof p就会得到
{
  name: string;
  age: number;
  address: {
    city: string;
  };
};

//那么
type Person = typeof p;

// 相当于
type Person = {
  name: string;
  age: number;
  address: {
    city: string;
  };
};

keyof

一个最基本的keyof用法如下,我们通过keyof Person得到一个PersonKeys类型,它是一个联合字面量类型,包含了Person所有的属性。所以我们在对类型为PersonKeys的变量赋值时,只能赋值为’name’或者’age’。

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

type PersonKeys = keyof Person;

const key1: PersonKeys = 'name';
const key2: PersonKeys = 'age';
// Type '"addr"' is not assignable to type 'keyof Person'.
const key3: PersonKeys = 'addr';

typeof和keyof一起使用

你可能已经知道,typeof 运算符为你提供对象的类型,上面例子中 Person interface,我们已经知道它的类型,所以我们只需要在 Person 上使用 keyof 操作符。
但是,当我们不知道对象的类型,或者我们只有一个值,类似于下面的情况,应该怎么办呢?

const bmw = { name: "BMW", power: "1000hp" }

这就是我们需要一起使用 keyof typeof 的地方。
typeof bmw 给到你他们的类型 { name: string, power: string }
接着 keyof 操作符给到你联合字面量类型,像下面代码描述的一样:

type CarLiteralType = keyof typeof bmw

let carPropertyLiteral: CarLiteralType
carPropertyLiteral = "name"       // OK
carPropertyLiteral = "power"      // OK
carPropertyLiteral = "anyOther"   // Error...Type '"anyOther"' is not assign

typeof和keyof和枚举一起使用

在 Typescript 中,enum 在编译时被用作类型,用来实现常量的类型安全,但是它们在运行时被视为对象。这是因为,当 Typescript 代码被编译为 Javascript 时,它们会被转换为普通对象。接着我们回顾一下,最开始我们提出问题的例子是这样的:

enum ColorsEnum {
    white = '#ffffff',
    black = '#000000',
}

这里 ColorsEnum 在运行时作为一个对象存在,不是一个类型,所以,我们需要一起使用 keyof typeof 这两个操作符,像下面代码展示的一样。

type Colors = keyof typeof ColorsEnum

let colorLiteral: Colors
colorLiteral = "white"  // OK
colorLiteral = "black"  // OK
colorLiteral = "red"    // Error...Type '"red"' is not assignable to type '"whi
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值