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
を使用すると、最初の試行と同じ結果になります。
各キーをそのキーの種類に依存するものにペアにしたい場合は、 マップ型 を使用してください。
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])[]
_