当我尝试忽略泛型外的属性时,它工作正常,但在泛型内会中断。基本上,问题是Omit<Thing, 'key1' | 'key2'>
变成了Omit<Thing, 'key1'> | Omit<Thing, 'key2'>
,并且typescript不允许使用Omit<Thing, 'key1'>
和Omit<Thing, 'key2'>
中的偶数键
现场演示: typescript Playground
export class AccessScope {
id!: number;
type!: string;
createdAt!: Date;
updatedAt!: Date;
}
type KeysWhichShouldBeOmitted = "id" | "createdAt" | "updatedAt";
type AccessScopeWithOmittedId = Pick<AccessScope, "type" | "createdAt" | "updatedAt">;
type OmitIfNotNull<
Entity,
Holder,
KeysToOmit,
> = KeysToOmit extends keyof Entity
? Omit<Holder, KeysToOmit>
: Holder;
type brokenType1 = OmitIfNotNull<
AccessScope,
AccessScopeWithOmittedId,
KeysWhichShouldBeOmitted
>
// Type '{ type: string; }' is not assignable to type 'brokenType1'.
// Property 'createdAt' is missing in type '{ type: string; }' but required in type 'Omit<Pick<AccessScope, "createdAt" | "updatedAt" | "type">, "updatedAt">'.(2322)
const brokenVar1: brokenType1 = {
type: 'asd'
}
// brokenType2 is fully visible version of brokenType1
type brokenType2 = Omit<Pick<AccessScope, "type" | "createdAt" | "updatedAt"> & Record<never, never>, "id">
| Omit<Pick<AccessScope, "type" | "createdAt" | "updatedAt"> & Record<never, never>, "createdAt">
| Omit<Pick<AccessScope, "type" | "createdAt" | "updatedAt"> & Record<never, never>, "updatedAt">
// Type '{ type: string; }' is not assignable to type 'brokenType1'.
// Property 'createdAt' is missing in type '{ type: string; }' but required in type 'Omit<Pick<AccessScope, "createdAt" | "updatedAt" | "type">, "updatedAt">'.(2322)
const brokenVar2: brokenType2 = {
type: 'asd'
}
type normalType = KeysWhichShouldBeOmitted extends keyof AccessScope
? Omit<AccessScopeWithOmittedId, KeysWhichShouldBeOmitted>
: AccessScopeWithOmittedId
const normalType: normalType = {
type: 'asd'
}
我尝试添加了扩展OmitIfNotNull
参数的各种奇怪变体
type OmitIfNotNull<
Entity extends Holder,
Holder extends Record<string, any>,
KeysToOmit extends keyof Entity,
> = KeysToOmit extends keyof Entity
? Omit<Holder, KeysToOmit>
: Holder;
1条答案
按热度按时间gblwokeq1#
此行为是由条件类型的分布特性引起的。您可以通过将
extends
子句的两侧括在方括号中来禁用此行为:Playground链接