-
-
Notifications
You must be signed in to change notification settings - Fork 231
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
Omit type doesn't work for deconstructor with rest #73
Comments
// @dts-jest:pass:snap -> Pick<Props, "name" | "visible"> | Pick<NewProps, "other">
Omit<Props | NewProps, 'age'> Historically it was introduced by some user request, I was not really sure about this change but now I think it's actually more harmful than useful. I might bring back previous behavior which was non-distributive. What do you think? |
I dig deeper and found another difference. I think that first scenario looks best if it worked. import { Omit, SetDifference } from 'utility-types'
type TGeneric<T extends string = string> = Extract<
| {age: number, pet: 'dog'}
| {age: number, pet: 'cat'}
,
{age: number, pet: T}
>
class Example<T extends 'dog' | 'cat' = 'dog' | 'cat'> {
public caseA: Omit<TGeneric<T>, 'age'>
public caseB: Pick<TGeneric<T>, SetDifference<keyof TGeneric<T>, 'age'>>
public constructor(arg1: TGeneric<T>) {
const {age, ...rest} = arg1
this.caseA = rest
// Scenario #1: I expect this to typecheck, but it complains, why?
this.caseB = rest
// Scenario #2: From Error message above I figured out a type that
// doesn't complain. What's the difference? Is this expected behavior?
this.caseA = rest as Omit<TGeneric<T>, 'age'>
// Scenario #3: At least this still works, but missed the type safety somewhat.
}
}
const lazyTypeGuard = (example: Example): example is Example<'cat'> => true
// I expect this to typecheck, but it errors. Why?
// Comments out `public caseB:` and it will typecheck.
// Therefore, scenario #3 is the only way that can typecheck the whole snippet. |
Typescript has in-build Perhaps lets bring the conversation to them about upcoming in-built |
@Akuukis Now it struck me that it might be related to the first example, no? :microsoft/TypeScript#28884 Sorry but the second example is unreadable to me, you should try to reduce and simplify it to a minimum possible. (First was good) |
Here is the simplification of your issue: const someScope = <T extends { age: number }>(pet: T) => {
const { age, ...rest } = pet;
const A: Omit<T, 'age'> = rest;
// Type 'Pick<T, Exclude<keyof T, "age">>' is not assignable to type 'Omit<T, "age">'.ts(2322)
}; And changing Omit to below fixes the issue: export type Omit<T extends object, K extends keyof T> = Pick<T, SetDifference<keyof T, K>> |
Also the new Omit is now the same implementation as build-in Omit coming in TypeScript v3.5 to be future compatible |
Please see the minimal reproducible example below and questions inline.
The text was updated successfully, but these errors were encountered: