Bug description
I've been using type-fest to replace some of the type utilities we have in our project, but when trying to use Except to replace our alternative version of Omit (which we needed because Omit loses known keys) I was getting errors due to the keyof ObjectType requirement in the keys. This doesn't seem to play well with conditional types and/or infer
For conditional types:
type Cond<T> =
T extends string ? {
name: string;
remove: string
}
: T extends number ? { prime: boolean }
: {}
type Removed<T> = Except<Cond<T>, "remove">
// ^ ---> Type 'string' does not satisfy the constraint 'keyof A<T>'.
// Type '"remove"' is not assignable to type '("remove" | "name") & keyof (T extends number ? { prime: boolean; } : {})'.
For infer, I've been working with the CompnentProps type from Vue, which is defined as:
type ComponentProps<T> =
T extends new (...args: any) => {
$props: infer P
} ? NonNullable<P>
: T extends (props: infer P, ...args: any) => any ? P
: {}
Trying to use Except with it runs into
type ComponentPropsLessKey<T> =
Except<ComponentProps<T>, "key">
// ^ ---> Type 'string' does not satisfy the constraint 'keyof ComponentProps<T>'.
// Type '"key"' is not assignable to type 'never'.
This seems to imply that keyof ComponentProps<T> resolves to never
I have a type that attempts to get the user defined props from a Vue component, and I get a similar type error as the above when attempting to use Except to define it:
type ComponentPropsUser<T> = Except<
ComponentProps<T>,
keyof VNodeProps
| keyof AllowedComponentProps
| keyof ComponentCustomProps // This is an empty interface by default as it is meant for extension by users
>
// ^ ---> Type 'string' does not satisfy the constraint 'keyof ComponentProps<T>'.
// Type 'string' is not assignable to type 'keyof ComponentProps<T>'.
// Type '"key"' is not assignable to type 'never'.
This might be better resolved by a version of Except that would be less strict in the types of the keys it expects, but I will leave it up to the project to decide if this is an issue worth fixing.
For reference, I currently use an alternative version of Omit defined as:
// Taken from https://stackoverflow.com/a/65673414
type AlternativeOmit<T, K extends PropertyKey> = {
[P in keyof T as Exclude<P, K>]: T[P]
};
Repro
https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBDAnmApnA3nAogDwMYpjwC+cAZlBCHAORKoC0ZKAzjDQNwCwAUKJLATI0mAMJVIAOxSSYABUpgWcUhSpwARADcArigZ4JEabIb19ACxQAbVFBYbuPXubjjJAEwA8AFQB8cAC8vHBwPnAoODAyHspsUMCSAOZwAPwYIaFwkgCGICgAXHDxiUlOWXBQKCAQWoXFMAnJmcSZReGR0Z7KkjogAEYoUGkYcGAJ+UX9EBDWKDmSKm0Yrc5rrgBK1bUo3v5B2PiEMF7ue34ANJpVNXUafrwuwm5GJvKKLAAyrCwA0iiIXwBYI8UK4AhEU6vGTvCBKIFXDQAawB90ePFc4nAxhhCjhLAAqiwhkCDuDjl5MlipLiPgjMijEBAyHAAGoAOQgHhQeKUmQAPnBGcy4ABBazWCAAd121Jxsl5LAFQoBIrlb1EOjYVEVvD8HCAA
Bug description
I've been using
type-festto replace some of the type utilities we have in our project, but when trying to useExceptto replace our alternative version ofOmit(which we needed becauseOmitloses known keys) I was getting errors due to thekeyof ObjectTyperequirement in the keys. This doesn't seem to play well with conditional types and/orinferFor conditional types:
For
infer, I've been working with theCompnentPropstype from Vue, which is defined as:Trying to use
Exceptwith it runs intoThis seems to imply that
keyof ComponentProps<T>resolves toneverI have a type that attempts to get the user defined props from a Vue component, and I get a similar type error as the above when attempting to use
Exceptto define it:This might be better resolved by a version of
Exceptthat would be less strict in the types of the keys it expects, but I will leave it up to the project to decide if this is an issue worth fixing.For reference, I currently use an alternative version of
Omitdefined as:Repro
https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBDAnmApnA3nAogDwMYpjwC+cAZlBCHAORKoC0ZKAzjDQNwCwAUKJLATI0mAMJVIAOxSSYABUpgWcUhSpwARADcArigZ4JEabIb19ACxQAbVFBYbuPXubjjJAEwA8AFQB8cAC8vHBwPnAoODAyHspsUMCSAOZwAPwYIaFwkgCGICgAXHDxiUlOWXBQKCAQWoXFMAnJmcSZReGR0Z7KkjogAEYoUGkYcGAJ+UX9EBDWKDmSKm0Yrc5rrgBK1bUo3v5B2PiEMF7ue34ANJpVNXUafrwuwm5GJvKKLAAyrCwA0iiIXwBYI8UK4AhEU6vGTvCBKIFXDQAawB90ePFc4nAxhhCjhLAAqiwhkCDuDjl5MlipLiPgjMijEBAyHAAGoAOQgHhQeKUmQAPnBGcy4ABBazWCAAd121Jxsl5LAFQoBIrlb1EOjYVEVvD8HCAA