私はタイプを持っています
type Foo = {
a: {
b: {
c: string[]
...rest
}
...rest
}
...rest
}
a.b.c
別のタイプに変更し、残りのプロパティを保持するにはどうすればよいですか?
TypeScriptはこれを行うための組み込みの方法を提供しないため、そのようなものが必要な場合は、マップされた条件付きタイプを使用して自分でビルドする必要があります。また、特にオプション/読み取り専用/ etcプロパティと関数/配列では、あらゆる種類の潜在的なエッジケースがあるため、必要な動作を正確に考慮する必要があります。
これを行う1つの方法は次のとおりです。
type _Overwrite<T, U> = U extends object ? (
{ [K in keyof T]: K extends keyof U ? _Overwrite<T[K], U[K]> : T[K] } & U
) : U
type ExpandRecursively<T> = T extends Function ? T : T extends object
? T extends infer O ? { [K in keyof O]: ExpandRecursively<O[K]> } : never
: T;
type Overwrite<T, U> = ExpandRecursively<_Overwrite<T, U>>
タイプは、_Overwrite<T, U>
型を取るT
とU
してからものを置き換える、そのプロパティを再帰的に歩くT
からのものとのU
競合がある場合。このタイプは機能するはずですが、交差点を使用して表現するため、醜くなる可能性があります。
だから、ExpandRecursively<T>
一緒にすべてのプロパティ結果の型およびマージをウォークスルータイプがあり、そう{a: string} & {b: number}
なるはず{a: string, b: number}
。
そして、結果Overwrite<T, U>
を取り入れ_Overwrite<T, U>
て使用ExpandRecursively<>
しているだけです。
例を使ってどのように動作するかを見てみましょう。
type Foo = {
a: {
b: {
c: string[];
d: number;
}
e: {
f: boolean;
}
};
g: {
h?: () => string;
}
}
type ReplaceFoo = Overwrite<Foo, { a: { b: { c: number } } }>;
これにより、次のようになります。
/*
type ReplaceFoo = {
a: {
b: {
c: number;
d: number;
};
e: {
f: boolean;
};
};
g: {
h?: (() => string) | undefined;
};
}
*/
これは私には合理的に見えます。しかし、使用する前に、このようなものを非常に徹底的にテストするT
必要U
があります。共用体タイプである場合、および/または共用体タイプである場合はどうしますか?配列またはタプルの場合、T
またはそれU
である場合はどうしますか?「置き換えあなたは間の区別を行うことができるようにしたいかとし、」置き換え「と」?(つまり、サブプロパティを「置換」する代わりに「消去」するオプションが必要ですか?)これらの質問(およびおそらく他の質問)に対するすべての回答は、どのように記述したいかに関係します。a.b.c
number
a.b
{c: number}
Overwrite<T, U>
それがあなたに前進する方法のいくつかのアイデアを与えることを願っています。幸運を!
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加