深入typescript之如何高效地获取变量类型

Posted 恪愚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入typescript之如何高效地获取变量类型相关的知识,希望对你有一定的参考价值。

假如我们有一个JSON对象,里边包含了name、age两个属性,我们可以通过一些TypeScript内置的工具函数来实现一些有意思的事情。
通过keyof与typeof组合可以得到我们想要的结果:

const obj = {
  name: 'Niko',
  age: 18
}

// 如果是这样的取值,只能写在代码中,不能写在 d.ts 文件中,因为声明文件里边不能存在实际有效的代码
type keys = keyof typeof obj

let a: keys = 'name' // pass
let b: keys = 'age'  // pass

let c: keys = 'test' // error

而如果我们想要将一个类型不统一的JSON修改为统一类型的JSON也可以使用这种方式:

const obj = {
  name: 'Niko',
  age: 18,
  birthday: new Date()
}

const infos: Record<keyof typeof obj, string> = {
  name: '',
  age: '',
  birthday: 123, // 出错,提示类型不匹配
  test: '', // 提示不是`info`的已知类型
}

keyof是索引类型查询操作符。

假设T是一个类型,那么keyof T产生的类型是T的属性名称字符串字面量类型构成的联合类型。

特别说明:T是数据类型,并非数据本身。

代码实例如下:

interface Itest{

  webName:string;

  age:number;

  address:string

}

type ant=keyof Itest;

如果T是一个带有字符串索引签名的类型,那么keyof T是 string 类型,并且T[string]为索引签名的类型。

代码实例如下:

interface Map<T> {

  [key: string]: T;

}

let keys: keyof Map<number>;//string

let value: Map<number>['antzone'];//number

那现在又有一个问题:如果要定义一个对象的 key 和 value 类型该怎么做呢?这时候就需要用到 TS 的 Record 了。

上代码:

interface PageInfo {
  title: string;
}

type Page = "home" | "about" | "contact";

const nav: Record<Page, PageInfo> = {
  about: { title: "about" },
  contact: { title: "contact" },
  home: { title: "home" },
};

很好理解,Record 后面的泛型就是对象键和值的类型。

比如我需要一个对象,有 ABC 三个属性,属性的值必须是数字,那么就这么写:

type keys = 'A' | 'B' | 'C'
const result: Record<keys, number> = {
  A: 1,
  B: 2,
  C: 3
}

以上是关于深入typescript之如何高效地获取变量类型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Typescript 中获取变量类型?

遨游TypeScript海洋之定义变量和数据类型

我在坑底的typescript手记之几种特殊的变量类型

我在坑底的typescript手记之几种特殊的变量类型

来做操吧!深入 TypeScript 高级类型和类型体操

关于typescript之定义变量和数据类型那点事