Record
是TypeScript的一种工具类,在版本2.1后,开箱即用
Record
Constructs an object type whose property keys are Keys and whose property values are Type. This utility can be used to map the properties of a type to another type.” — TypeScript’s documentation
译:构造一个对象类型,
Keys
表示对象的属性键 、Type
表示对象的属性值,用于将一种类型属性映射到另一种类型
从表面上看,Record
创建了一个拥有Keys
类型的属性和对应值的Type
的对象。有一个能实现相似功能的是使用 索引签名, 那么为什么我们要使用Record
类型呢?有什么不同和作用呢?
在TypeScript
中,我们访问带有方括号的对象的方式称为索引签名。 它广泛用于具有未知字符串键和特定值的对象类型。下面是一个例子:
type studentScore = { [ name:string]:number }
上面的索引签名示例也可以使用Record
类型表示
type studentScore = Record<string, number>
对于这个用例,从类型断言的角度看,这两种类型的声明的作用是一致的。从语法的角度看,索引签名是更好些,因为其中的name
的键表达式更清晰的表达了它的意图,并在vscode
的展示中更智能感知。
所以,为什么我们要去使用Record
类型呢?
Record
类型的好处是简明的。当我们想要去限制属性时,也就是Record
类型大显身手的时候。下面的示例是我们在Record
中使用联合字符串去限制属性键
type roles = 'tester' | 'developer' | 'manager'
const staffCount: Record<roles, number> = {
tester: 10,
developer: 20,
manager: 1
}
在示例中,我们使用联合类型约束定义了一个类型。如果我们尝试去访问一个不在联合类型中的属性时,VS Code
编译器会进行提示。当我们维护一个复杂类型的时候这非常有用,因为编译器会阻止这类错误的发生。
另一个有用的功能是keys
可以是枚举。在下面的例子中,我们使用staffTypes
枚举作为Record
类型的限制值,因此可读性更好。请注意,尽在TypeScript
2.9之后才支持枚举。因此,在2.9版本之前,key的类型被限制为string类型
通过使用keyof
从现有类型中获取所有的属性,并和字符串组合,我们可以做如下事情:
interface Staff {
name:string,
salary:number,
}
type StaffJson = Record<keyof Staff, string>
const product: StaffJson = {
name: 'John',
salary:'3000'
}
当你想要保留现有类型的属性但将值类型转换为其他类型时,这很便捷。
Record
类型可以和其他的工具类型一起使用,可以实现更高级的用法。
type seniorRole = 'manager'
type technicalRole = 'developer'
const benefits: Partial<Record<seniorRole, 'Free Parking'> & Record<technicalRole, 'Free Coffee'>> = {};
benefits.manager = 'Free Parking';
benefits.developer = 'Free Parking';//ERROR: no free parking for dev
通过 Record
、Partial
和 Intersection
类型一起工作,此代码创建了一个强类型的benefits
对象,并在键和值类型之间建立关联.强类型对象使得在编译时更容易捕获错误,使 IDE 在键入时更容易标记错误,并提供具有自动完成功能的智能提示
Record
是一个有用和简要的工具类型,可以让你的代码更健壮。如果你有其他关于如何最好地使用它的想法,请在评论区与我和您的开发人员同事分享。
我是废材壶,前端开发者,欢迎微信搜一搜「 CodeLife集」阅读不迷路
【原文地址】