Typescript中括号和keyof的几个特殊用法

Posted 天地会珠海分舵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Typescript中括号和keyof的几个特殊用法相关的知识,希望对你有一定的参考价值。

1. 支持任意属性的接口

有时候我们希望一个接口允许有任意的属性,可以使用如下方式:

interface Person {
    name: string;
    age?: number;
    [propName: string]: any;
}

let tom: Person = {
    name: 'Tom',
    gender: 'male'
};

使用 [propName: string] 定义了任意属性取 string 类型的值。

需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集

interface Person {
    name: string;
    age?: number;
    [propName: string]: string;
}

let tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};

// index.ts(3,5): error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.
// index.ts(7,5): error TS2322: Type '{ [x: string]: string | number; name: string; age: number; gender: string; }' is not assignable to type 'Person'.
//   Index signatures are incompatible.
//     Type 'string | number' is not assignable to type 'string'.
//       Type 'number' is not assignable to type 'string'.

上例中,任意属性的值允许是 string,但是可选属性 age 的值却是 number,number 不是 string 的子属性,所以报错了。

另外,在报错信息中可以看出,此时

{ name: 'Tom', age: 25, gender: 'male' }

的类型被推断成了

 { [x: string]: string | number; name: string; age: number; gender: string; }

这是联合类型和接口的结合。

一个接口中只能定义一个任意属性。如果接口中有多个类型的属性,则可以在任意属性中使用联合类型:

interface Person {
    name: string;
    age?: number;
    [propName: string]: string | number;
}

let tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};

2. 获取接口属性类型的联合值

interface Student {
   name: string;
   age: number;
}

这时如果我们对interface使用keyof

type propKeys = keyof Student // name | age

我们知道输出的是以接口属性的键命组成的联合类型: ‘name’ | 'age’
这时我们如果要获得各个键的属性所组成的联合类型,比如上面的string和number,可以这样做

type propTypes = Student[keyof Student]

这里的propTypes就是个联合类型: string | number

3. in keyof 用法示例

interface BrowserCache {
    TOKEN_CACHE: string;
    ID_CACHE: number;
}


type TCacheExpiretTime = {
    [key in keyof BrowserCache]: Date;
}

TCacheExpireTime最终类型推断将会是

type TCacheExpiretTime = {
    TOKEN_CACHE: Date | undefined;
    ID_CACHE: Date | undefined;
}

如果想每个属性可选,可将代码修改成

type TCacheExpiretTime = {
    [key in keyof BrowserCache]?: Date;
}

TCacheExpireTime最终类型推断将会是

type TCacheExpiretTime = {
    TOKEN_CACHE?: Date | undefined;
    ID_CACHE?: Date | undefined;
}

《待续》今后碰到相关用法在这里记录下,充当笔记。

参考

  1. http://ts.xcatliu.com/basics/type-of-object-interfaces.html

以上是关于Typescript中括号和keyof的几个特殊用法的主要内容,如果未能解决你的问题,请参考以下文章

Typescript中括号和keyof的几个特殊用法

Typescript中括号和keyof的几个特殊用法

Typescript 'keyof' 关键字在使用 react setState 函数时出错

TypeScript keyof 和 typeof

[TypeScript] Query Properties with keyof and Lookup Types in TypeScript

TypeScript 中的“keyof typeof”是啥意思?