我有一个这样的界面:
export interface Campaign {
id: string
orders?: number
avgOrderValue?: number
optionalAttributes: string[]
attributeValues: {
optionalAttributes: CampaignAttribute[]
mandatoryAttributes: CampaignAttribute[]
values?: { [key: string]: unknown }
}
created: number
lastUpdated: number
}
Run Code Online (Sandbox Code Playgroud)
我想为我的表单创建一个类型,需要在界面中省略attributeValues.optionalAttributes
和。attributeValues.mandatoryAttributes
我在想也许 Typescript 可以做这样的事情:
export type CampaignFormValues = Omit<Campaign, 'attributeValues.mandatoryAttributes'>
Run Code Online (Sandbox Code Playgroud)
但这行不通。
我使用了这个问题的答案:Deep Omit with typescript 但这个答案只是深度省略了每个匹配的键,所以像这样使用它:
export type CampaignFormValues = Omit<Campaign, 'optionalAttributes'>
Run Code Online (Sandbox Code Playgroud)
还会删除optionalAttributes
我想保留的根级别。
有没有办法用 Typescript 进行嵌套省略?
首先,省略attributeValues
,然后将其添加回来并删除属性。
export interface Campaign {
id: string
attributeValues: {
optionalAttributes: string[]
mandatoryAttributes: string[]
values?: { [key: string]: unknown }
}
}
type ChangeFields<T, R> = Omit<T, keyof R> & R;
type CampaignForm = ChangeFields<Campaign, {
attributeValues: Omit<Campaign['attributeValues'], 'mandatoryAttributes'|'optionalAttributes'>
}>;
const form: CampaignForm = {
id: '123',
attributeValues: {
values: { '1': 1 }
}
}
Run Code Online (Sandbox Code Playgroud)
type A = {
a: {
b: string
c: string
}
x: {
y: number
z: number,
w: {
u: number
}
}
}
type Primitives = string | number | boolean | symbol
/**
* Get all valid nested pathes of object
*/
type AllProps<Obj, Cache extends Array<Primitives> = []> =
Obj extends Primitives ? Cache : {
[Prop in keyof Obj]:
| [...Cache, Prop] // <------ it should be unionized with recursion call
| AllProps<Obj[Prop], [...Cache, Prop]>
}[keyof Obj]
type Head<T extends ReadonlyArray<any>> =
T extends []
? never
: T extends [infer Head]
? Head
: T extends [infer Head, ...infer _]
? Head
: never
type Tail<T extends ReadonlyArray<any>> =
T extends []
? []
: T extends [infer _]
? []
: T extends [infer _, ...infer Rest]
? Rest
: never
type Last<T extends ReadonlyArray<any>> = T['length'] extends 1 ? true : false
type OmitBase<Obj, Path extends ReadonlyArray<any>> =
Last<Path> extends true
? {
[Prop in Exclude<keyof Obj, Head<Path>>]: Obj[Prop]
} : {
[Prop in keyof Obj]: OmitBase<Obj[Prop], Tail<Path>>
}
// we should allow only existing properties in right order
type OmitBy<Obj, Keys extends AllProps<Obj>> = OmitBase<A, Keys>
type Result = OmitBy<A,['a', 'b']> // ok
type Result2 = OmitBy<A,['b']> // expected error. order should be preserved
Run Code Online (Sandbox Code Playgroud)
更多解释你可以在我的博客中找到
上述解决方案适用于深层嵌套类型
如果您想使用点语法prop1.prop2
,请考虑下一种类型:
type Split<Str, Cache extends string[] = []> =
Str extends `${infer Method}.${infer Rest}`
? Split<Rest, [...Cache, Method]>
: Str extends `${infer Last}`
? [...Cache, Last,]
: never
type WithDots = OmitBy<A, Split<'a.b'>> // ok
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15839 次 |
最近记录: |