Record<K, T>
在Typescript中的含义是什么?
Typescript 2.1引入了Record
类型,在一个例子中描述它:
// For every properties K of type T, transform it to U function mapObject<K extends string, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>
Advanced Types页面在Record
,Readonly
和Partial
的映射类型标题下提到Pick
,似乎是它的定义:
type Record<K extends string, T> = { [P in K]: T; }
Readonly,Partial和Pick是同态的,而Record不是。 Record不是同态的一个线索是它不需要输入类型来复制属性:
type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>
就是这样。除了上面的引用,还没有提到Record
上的typescriptlang.org。
Record
的简单定义吗?Record<K,T>
只是说“这个物体上的所有属性都有T
类型”吗?可能不是所有的属性,因为K
有一些目的......K
是否禁止对象上的其他键不是K
,还是允许它们只是表明它们的属性没有转换为T
?type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>
它跟这个完全一样吗?:
type ThreeStringProps = {prop1: string, prop2: string, prop3: string}
- 有人可以给出
Record
的简单定义吗?
Record<K, T>
是一种对象类型,其属性键为K
,其属性值为T
。也就是说,keyof Record<K, T>
相当于K
,而Record<K, T>[K]
(基本上)相当于T
。
Record<K,T>
只是说“这个物体上的所有属性都有T
类型”吗?可能不是所有的对象,因为K
有一些目的......
如你所知,K
有一个目的......将属性键限制为特定值。如果你想接受所有可能的字符串值键,你可以做类似Record<string, T>
的事情,但这样做的惯用方法是使用像index signature这样的{ [k: string]: T }
。
K
是否禁止对象上的其他键不是K
,还是允许它们只是表明它们的属性没有转换为T
?
它并不完全“禁止”其他密钥:毕竟,一般来说,一个值通常允许在其类型中没有明确提到的属性......但是它不会识别出存在这样的属性:
declare const x: Record<"a", string>;
x.b; // error, Property 'b' does not exist on type 'Record<"a", string>'
并将它们视为excess properties,有时被拒绝:
declare function acceptR(x: Record<"a", string>): void;
acceptR({a: "hey", b: "you"}); // error, Object literal may only specify known properties
有时接受:
const y = {a: "hey", b: "you"};
acceptR(y); // okay
- 以给定的例子:
type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>
它跟这个完全一样吗?:type ThreeStringProps = {prop1: string, prop2: string, prop3: string}
是!
希望有所帮助。祝好运!
记录允许您从联盟创建新类型。 Union中的值用作新类型的属性。
例如,假设我有一个像这样的联盟:
type CatNames = "miffy" | "boris" | "mordred";
现在我想创建一个包含所有猫的信息的对象,我可以使用CatName Union中的值作为键创建一个新类型。
type CatList = Record<CatNames, {age: number}>
如果我想满足这个CatList,我必须创建一个这样的对象:
const cats:CatList = {
miffy: { age:99 },
boris: { age:16 },
mordred: { age:600 }
}
您的类型安全性非常强:
我最近用它来创建一个Status组件。组件将接收状态道具,然后呈现图标。为了说明的目的,我在这里简化了很多代码
我有一个像这样的工会:
type Statuses = "failed" | "complete";
我用它来创建这样的对象:
const icons: Record<
Statuses,
{ iconType: IconTypes; iconColor: IconColors }
> = {
failed: {
iconType: "warning",
iconColor: "red"
},
complete: {
iconType: "check",
iconColor: "green"
};
然后我可以通过将对象中的元素解构为道具来渲染,如下所示:
const Status = ({status}) => <Icon {...icons[status]} />
如果稍后扩展或更改了Statuses union,我知道我的Status组件将无法编译,我将收到一个错误,我可以立即修复。这允许我向应用程序添加其他错误状态。
请注意,实际应用程序有多个错误状态,这些错误状态在多个位置引用,因此这种类型的安全性非常有用。