gpt4 book ai didi

typescript - DeepMerge<> 通用不支持深度可选

转载 作者:搜寻专家 更新时间:2023-10-30 21:07:53 25 4
gpt4 key购买 nike

我有一个 DeepMerge<>下面的泛型不支持深度可选合并。

type DeepMerge<T, U> = [T, U] extends [object, object] ?
{
[K in keyof (U & Pick<T, Exclude<keyof T, keyof U>>)]: (
K extends keyof U ? (
K extends keyof T ? DeepMerge<T[K], U[K]> : U[K]
) : (
K extends keyof T ? T[K] : never
)
)
} : U;

我有一个 Person带有深可选 address .

type Person = {
name: string,
age: number,
address: {
line1: string,
line2: string | null | number,
zip: string | number,
address?: {
line1: string,
line2: string | null | number,
zip: string | number,
},
},
};

我想覆盖深address并添加 burger .

type PersonOverwrites = {
address: {
pizzaDelivery: boolean,
address?: {
burger: boolean,
},
},
};

这是提示:

const person: DeepMerge<Person, PersonOverwrites> = {
name: 'Thomas',
age: 12,
address: {
line1: 'hi',
line2: 'hi',
zip: 'hi',
pizzaDelivery: true,
address: {
line1: 'hi',
line2: 'hi',
zip: 'hi',
burger: true,
},
},
};

它应该需要 line1 , line2 , zip , burger .

enter image description here

Type '{ line1: string; line2: string; zip: string; burger: true; }' is not assignable to type '{ burger: boolean; }'. Object literal may only specify known properties, and 'line1' does not exist in type '{ burger: boolean; }'.

应该是支持{ line1: string; line2: string; zip: string; burger: true; }但整个深层对象都被覆盖为 { burger: boolean; } .

最佳答案

嗯,我认为这里的问题是 keyof ({a: string} | undefined) 显示为 never 所以只要该属性是可选的, DeepMerge 无法再向下递归。可能还有其他方法可以解决此问题,但首先,如何将 TU 更改为它们自身的 NonNullable 版本,其中 NonNullabledefined in the standard library作为

type NonNullable<T> = T extends null | undefined ? never : T;

让我们试试看:

type DeepMerge<_T, _U, T= NonNullable<_T>, U= NonNullable<_U>> =
[T, U] extends [object, object] ?
{
[K in keyof (U & Pick<T, Exclude<keyof T, keyof U>>)]: (
K extends keyof U ? (
K extends keyof T ? DeepMerge<T[K], U[K]> : U[K]
) : (
K extends keyof T ? T[K] : never
)
)
} : U;

那有用吗?将 person 的类型推断为

const person: {
address: {
pizzaDelivery: boolean;
address?: {
burger: boolean;
line1: string;
line2: string | number | null;
zip: string | number;
} | undefined;
line1: string;
line2: string | number | null;
zip: string | number;
};
name: string;
age: number;
}

编辑:也有可能你想要的只是 distribute across all unions ,像这样:

type DeepMerge<T, U> = T extends any ? U extends any ?
[T, U] extends [object, object] ?
{
[K in keyof (U & Pick<T, Exclude<keyof T, keyof U>>)]: (
K extends keyof U ? (
K extends keyof T ? DeepMerge<T[K], U[K]> : U[K]
) : (
K extends keyof T ? T[K] : never
)
)
} : U : never : never;

也许这对你更有效?

希望对您有所帮助。祝你好运!

关于typescript - DeepMerge<> 通用不支持深度可选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54635813/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com