# 六、keyof 和 typeof 类型操作符

# 1.keyof 操作符

对一个对象类型使用keyof操作符,会返回该对象属性名组成的一个字符串或者数字字面量的联合。

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

但如果这个类型有一个 string 或者 number 类型的索引签名,keyof 则会直接返回这些类型:

type Array1 = { [index: number]: unknown };
type A = keyof Array1; // type A = number

type Map1 = { [k: string]: boolean };
type M = keyof Map1; // type M = string | number

注意在这个例子中,M 是 string | number,这是因为 JavaScript 对象的属性名会被强制转为一个字符串,所以 obj[0]obj["0"] 是一样的。

来看下面的场景,我们希望返回对象中指定key的值

function returnObjVa(obj, key) {
    return obj[key];
}

可以预期到,输入正确的 key 则会返回期望的结果,否则就是 undefined,而使用Ts后我们希望避免这样的情况。

我们希望获取一个对象给定属性名的值,为此,我们需要确保我们不会获取 obj 上不存在的属性。所以我们在两个类型之间建立一个约束:

// 雏形
function returnObjVal<T, K>(obj: T, key: K){
    return obj[key];
}

// good
function returnObjVal<T, K extends keyof T>(obj: T, key: K){
    // (parameter) key: K extends keyof T
    return obj[key];
}

# 2.typeof 操作符

TypeScript 添加的 typeof 方法可以在类型上下文(type context)中使用,用于获取一个变量或者属性的类型。

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

如果仅仅用来判断基本的类型,自然是没什么太大用,和其他的类型操作符搭配使用才能发挥它的作用。

举个例子:比如搭配 TypeScript 内置的 ReturnType<T>。你传入一个函数类型,ReturnType<T> 会返回该函数的返回值的类型:

type funcType = (str: string) => boolean;
type n = ReturnType<funcType>; // type n = boolean

如果我们直接对一个函数名使用 ReturnType ,我们会看到这样一个报错:

function f() {
    return { x: 10, y: 3 };
}
type P = ReturnType<f>; // 泛型类型“ReturnType”需要 1 个类型参数

为了传入一个类型,我们需要借助 typeof

function f() {
    return { x: 10, y: 3 };
}

// 获取函数类型
type typeFn = typeof f;
// type typeFn = () => {
//     x: number;
//     y: number;
// }
type returnTypeFn = ReturnType<typeFn>
// type typeFn = () => {
//     x: number;
//     y: number;
// }

# 2.1 对对象使用 typeof

我们可以对一个对象使用 typeof,他会推导出这个对象的类型:

const obj = { name: "kevin", age: "18" };
type objT = typeof obj;
// type objT = {
//     name: string;
//     age: string;
// }

# 2.2 对函数使用 typeof

我们也可以对一个函数使用 typeof:

function identity<Type>(arg: Type): Type {
    return arg;
}

type identityT = typeof identity; // type identityT = <Type>(arg: Type) => Type

# 写在最后

参考:

欢迎Star⭐️

Last Updated: 12/24/2022, 9:40:42 AM