关于typescript2.0:typescript中的Record类型是什么?

What is the Record type in typescript?

Record在打字稿中是什么意思?

Typescript 2.1引入了Record类型,并在示例中进行了描述:

1
2
// 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>

见打字稿2.1

"高级类型"页面在"映射类型"标题下的ReadonlyPartialPick旁边提到了Record,其定义如下:

1
2
3
type Record<K extends string, T> = {
    [P in K]: T;
}

Readonly, Partial and Pick are homomorphic whereas Record is not. One clue that Record is not homomorphic is that it doesn’t take an input type to copy properties from:

1
type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>

就是这样。除了上面的引用,typescriptlang.org上没有其他提及Record的内容。

问题

  • 有人可以给出Record是什么的简单定义吗?

  • Record只是一种说法"此对象上的所有属性都将具有类型T"的方式吗?可能不是所有属性,因为K具有某些用途...

  • K泛型是否在对象上禁止非K的其他键,或者是否允许它们并且仅指示其属性未转换为T

  • 对于给定的示例:

    1
     type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>
  • 与此完全一样吗?:

    1
        type ThreeStringProps = {prop1: string, prop2: string, prop3: string}


  • Can someone give a simple definition of what Record is?
  • Record是一种对象类型,其属性键是K,其属性值是T。也就是说,keyof Record等效于KRecord[K](基本上)等效于T

  • Is Record merely a way of saying"all properties on this object will have type T"? Probably not all objects, since K has some purpose...
  • 如您所述,K的目的是...将属性键限制为特定值。如果要接受所有可能的字符串值键,则可以执行类似Record的操作,但是惯用的方式是使用诸如{ [k: string]: T }的索引签名。

  • Does the K generic forbid additional keys on the object that are not K, or does it allow them and just indicate that their properties are not transformed to T?
  • 它并没有完全"禁止"其他键:毕竟,通常允许一个值具有其类型中未明确提及的属性...但是它无法识别此类属性的存在:

    1
    2
    declare const x: Record<"a", string>;
    x.b; // error, Property 'b' does not exist on type 'Record<"a", string>'

    并将它们视为有时会被拒绝的多余属性:

    1
    2
    declare function acceptR(x: Record<"a", string>): void;
    acceptR({a:"hey", b:"you"}); // error, Object literal may only specify known properties

    有时被接受:

    1
    2
    const y = {a:"hey", b:"you"};
    acceptR(y); // okay
  • With the given example:

    1
    type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>

    Is it exactly the same as this?:

    1
    type ThreeStringProps = {prop1: string, prop2: string, prop3: string}
  • 是!

    希望能有所帮助。祝好运!


    记录使您可以从联合创建新类型。联合中的值用作新类型的属性。

    例如,假设我有一个这样的联合体:

    1
    type CatNames ="miffy" |"boris" |"mordred";

    现在,我想创建一个包含有关所有猫的信息的对象,我可以使用CatName Union中的值作为键来创建新类型。

    1
    type CatList = Record<CatNames, {age: number}>

    如果要满足此CatList,必须创建一个这样的对象:

    1
    2
    3
    4
    5
    const cats:CatList = {
      miffy: { age:99 },
      boris: { age:16 },
      mordred: { age:600 }
    }

    您将获得非常强大的类型安全性:

    • 如果我忘记了猫,就会报错。
    • 如果我添加了不允许的猫,则会出现错误。
    • 如果以后更改CatNames,则会收到错误消息。这特别有用,因为CatNames可能是从另一个文件导入的,并且可能在许多地方使用。

    实际的React示例。

    我最近使用它来创建状态组件。该组件将收到状态道具,然后呈现一个图标。为了说明起见,我在这里简化了很多代码

    我有一个这样的工会:

    1
    type Statuses ="failed" |"complete";

    我用它来创建这样的对象:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const icons: Record<
      Statuses,
      { iconType: IconTypes; iconColor: IconColors }
    > = {
      failed: {
        iconType:"warning",
        iconColor:"red"
      },
      complete: {
        iconType:"check",
        iconColor:"green"
      };

    然后,我可以通过将对象中的元素分解为道具来进行渲染,如下所示:

    1
    const Status = ({status}) => <Icon {...icons[status]} />

    如果以后扩展或更改状态联合,则我知道状态组件将无法编译,并且会收到一个错误,可以立即修复。这使我可以向应用程序添加其他错误状态。

    请注意,实际的应用程序具有在多个位置引用的数十个错误状态,因此这种类型的安全性非常有用。