Typescript 签名索引(索引访问类型)和类型操作符keyof/typeof

292 阅读3分钟

操作符有keyof 和typeof两种

  1. keyof 顾名思义是获取key值,可以获取接口和类型的keys, 如果类型是数组那keys则是number和数组的属性方法, 一定要是一个type类型或者interface接口。let或者const对象值是不可以的。class类(的实例?)却可以具体不再阐述了。 还有一些特殊的类型, 如约定key是number或者string类型的。下面是一些例子
  • 接口和类型的keys
interface Person {
    name: string,
    age: number
}
type PersonKeys = keyof Person
// PersonKeys = 'name'|'age', 
let keyName: keyof Person = 'name'
// 也可以是age,当然这种基本很少使用,我们在这只是介绍一下他可以是哪个值

type Students = { name: string, id: number }
type StudentsKeys = keyof Students
// 类型也是一样可以通过keyof获取类型的key值
  • 数组的keys
type List = { name: string, id: number }[]
type ListKeys = keyof List
// number | 'length' | 'sort'...
  • let或者const对象值是不可以的。class类(的实例?)却可以
const Times = {
    year: '2023',
}
type TimesKeys = keyof Times
// 如果是个值就不可以了, 会提示报错,但是如果再加上typeof就可以了 这个typeof时候再具体阐述

class Days {
    time: '2023'
}
type DaysKey = keyof Days
// time
  • 特殊的类型,约定key是number或者string类型
type NumKeyNameObj<T> = { [keyName: number]: string }
type NumKeyNameObjKeys = keyof NumKeyNameObj<unknown>
// keys 实际是 number

type StrKeyNameObj<T> = { [keyName: string]: T }
type StrKeynameObjKeys = keyof StrKeyNameObj<unknown>
// keys 实际是number | string
// 这是为什么

实际中更多的用于函数中两个参数约束的(T, K extends keyof T)

2.typeof 顾名思义是要得到类型的。与keyof相反, const let声明的值可以通过typeof获取。而keyof近一步操作就可以获取值的key。数组中值的类型获取则是直接输入number。 值必须要声明,是会报错的。简单数据类型值的声明必须let,用const声明简单类型,typeof会得到声明的值而不是类型。同时要是必选参数。 内置的ReturnType方法。如下面的实例

  • typeof获取const let声明的复杂类型、与keyof结合,获取值的key、数组中值的类型
const student = { name: 'hh', age: 11 }
type StudentType = typeof student
// {name:string, age:number}

type StudentKey = keyof typeof student
// name | age

const school = ['classA', 'classB', 'classC']
type schoolType = typeof school[number]
// string
  • 值必须要声明、简单数据类型值的声明必须let,const不可以、
type Types = typeof 'hh'
// 会报错

const num = '1'
type NumType = typeof num 
// '1'

let numb = '1'
type Numbtype = typeof numb
//string
  • 要是必选参数
const newPerson = {
    name: 'hh',
    age: 66,
    son: [{
        name: '22',
        id: 1,
    }]
}
type PersonType = typeof newPerson['son'][number]
//{name: string; id:number}
如果约定son是一个可选项那么,就可能会报错 。。。待验证。。。
  • ReturnType内置方法,返回函数返回值的类型
function students() {
    return {name:'hh', id: 11}
}
type StudentsType = ReturnType<typeof students>
//{name:string, id: number}

  • 枚举的使用
enum UserResponse {
  No = 0,
  Yes = 1,
}

type result = keyof typeof UserResponse;
  1. 签名索引。索引名本身就是一个类型,所以我们也可以使用联合、keyof 或者其他类型,数组索引。别名替代key要用type声明
  • 索引类型
type Person = {name: string, age: number}
type NameType = Person['name']
type Type = Person['name' | 'age']
type Types =  Person[keyof Person]
// 数组索引
const MyArray = [
  { name: "Alice", age: 15 },
  { name: "Bob", age: 23 },
];
       
type Age = typeof MyArray[number]["age"];  
  • 别名替代索引key
type key = "age";
type Age = Person[key]
interface Info{
    name: string,
    age: number
}
let infoProp: keyof Info
//name | age
infoProp = 'age' 
interface Obj<T> {
  [key: number]: T;
}
// key | number
const key: keyof Obj<number>

链接:
www.5axxw.com/questions/c… zhoujunxiong.gitee.io/2020/08/31/… ts.yayujs.com/handbook/In… www.jianshu.com/p/f6c91fa0a…