TypescriptでRecord<K, T>
はどういう意味ですか?
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>
TypeScript 2.1 を参照してください。
そして、 高度な型 のページでは、その定義はRecord
、Readonly
、およびPartial
と並んで、マップ型の見出しの下にPick
があります。
type Record<K extends string, T> = { [P in K]: T; }
Readonlyでは、PartialとPickは準同型であり、Recordはそうではありません。 Recordは準同型ではないという1つの手がかりは、プロパティをコピーするのに入力タイプを使用しないことです。
type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>
以上です。上記の引用の他に、 typescriptlang.org に関するRecord
についての他の言及はありません。
誰かが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>
のようなことをすることができますが、そのための慣用的な方法は インデックスシグネチャを使うことです{ [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>'
そしてそれはそれらを 過剰なプロパティ として扱い、それらは時々拒絶されます:
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から新しいタイプを作成できます。 Unionの値は新しい型の属性として使用されます。
たとえば、私はこのような連合があるとします。
type CatNames = "miffy" | "boris" | "mordred";
これで、すべての猫に関する情報を含むオブジェクトを作成したいと思います。CatNameUnionの値をキーとして使用して、新しい型を作成できます。
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]} />
ステータスの共用体が後で拡張または変更された場合、私は自分のStatusコンポーネントがコンパイルに失敗することを知っていて、すぐに修正できるというエラーが出ます。これにより、アプリにエラー状態を追加することができます。
実際のアプリには、複数の場所で参照される数十のエラー状態があるため、このタイプの安全性は非常に役立ちました。