web-dev-qa-db-ja.com

TypeScriptキー値リレーション保存Object.Entries型

TypeScriptによって提供されたObject.entriesの入力は、戻り型[string, T][]を持ちますが、汎用型Entries<O>を検索して、キーと値の関係を保持するこの関数の戻り値を表します。

例えば。オブジェクトタイプを持つとき

type Obj = {
    a: number,
    b: string,
    c: number
}

Objを指定しても、下のタイプの1つ(または似たもの)になるタイプEntries<O>を探しています。

(["a", number] | ["b", string] | ["c", number])[]
[["a", number], ["b", string], ["c", number]]
(["a" | "c", number] | ["b", string])[]

これは、Object.entriesのすべてのユースケースに対して正しくないこと( こちらを参照 )私の特定の場合には問題ありません。


ソリューションの試行錯誤:

type Entries<O> = [keyof O, O[keyof O]][]は、可能なキーと値を保持するだけでなく、これらの間の関係はEntries<Obj>ではなく、これらの間の関係は["a" | "b" | "c", number | string]です。

type Entry<O, K extends keyof O> = [K, O[K]]
type Entries<O> = Entry<O, keyof O>[]

ここでは、Entryの定義が予想どおりに機能します。 Entry<Obj, "a">["a", number]ですが、2番目のタイプ変数として2行目にkeyof Oを使用すると、最初の試行と同じ結果になります。

8

各キーをそのキーの種類に依存するものにペアにしたい場合は、 マップ型 を使用してください。

type Entries<T> = {
    [K in keyof T]: [K, T[K]];
}[keyof T][];

type Test = Entries<Obj>;
// (["a", number] | ["b", string] | ["c", number])[]
 _

2番目のバージョンは、共用体の代わりにプロパティを含むタプルタイプを持ち、構築するのははるかに難しいです。 組合をタプルに変換することは可能です しかしあなたは基本的にはそれをするべきではありません。

3番目のバージョンは管理できますが、最初のバージョンよりも少し複雑になります。PickByValue from この回答

type Entries3<T> = {
    [K in keyof T]: [keyof PickByValue<T, T[K]>, T[K]]
}[keyof T][];

type Test3 = Entries3<Obj>;
// (["a" | "c", number] | ["b", string])[]
 _

遊具リンク

5
kaya3