-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Bug in Pick and Discriminated Unions #28791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is working as intended. You are using |
Hi, Thanks for the reply but I don't quite understand. The error is not related to name but to variant? |
@cliedeman Please post a complete repro. The current example starts with two undefined types. |
Updated |
Ah, I see what's going on. The issue is that type A = { name?: string, variant: 'a' };
type B = { name?: string, variant: 'b' };
type C = A | B;
type X = Omit<C, 'name'>; // { variant: 'a' | 'b' } Because There are two ways you can fix the issue. The simplest is to declare type C = { name?: string, variant: 'a' | 'b' }; The other is to make export type AllKeys<T> = T extends T ? keyof T : never;
export type Omit<T, K extends AllKeys<T>> = T extends T ? Pick<T, Exclude<keyof T, K>> : never; This may look a bit odd, but the When you use the distributive form of type A = { name?: string, variant: 'a' };
type B = { name?: string, variant: 'b' };
type C = A | B;
type X = Omit<C, 'name'>; // { variant: 'a' } | { variant: 'b' } and For the reason why we don't treat the two forms of |
@ahejlsberg I have a somewhat related issue and I wonder if it's worth opening a separate ticket. In the following example, when excluding some keys from a generic type, the resulting type doesn't contain properties which are meant to be there according to the base type constraint: function excludeTag<T extends { tag: string, foo: string }>(obj: T) {
let { tag, ...rest } = obj;
let manual: Pick<T, Exclude<keyof T, "tag">>
// 'foo' doesn't exist
rest.foo;
// 'foo' doesn't exist
manual.foo;
return rest;
}
const result = excludeTag({
tag: 'point',
foo: 'bar'
});
// 'foo' exists
result.foo; Please, note that the manually created type used to work in Edit: I feel like #28752 is also somehow related. |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Please, please! Add some explanation, why is this behaviour intended. |
Ran into this today; this article was helpful. |
TypeScript Version: 3.2.1
Search Terms: Discriminated Unions, Pick, Exclude
Expected behavior:
Compiles
Actual behavior:
Errors with incompatible types for variant
Playground Link:
Related Issues:
#27201 (comment)
#28274
but these were related to generics so I could not be sure if this is a duplicate or not
The text was updated successfully, but these errors were encountered: