Skip to content

Results of conditional types are not comparable (regression) #30049

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

Open
falsandtru opened this issue Feb 22, 2019 · 1 comment
Open

Results of conditional types are not comparable (regression) #30049

falsandtru opened this issue Feb 22, 2019 · 1 comment
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@falsandtru
Copy link
Contributor

falsandtru commented Feb 22, 2019

@RyanCavanaugh @weswigham @ahejlsberg Caused by #27697

TypeScript Version: 3.4.0-dev.20190222

Search Terms:

Code

type Falsy = undefined | false | 0 | '' | null | void;

type TEq<T, U> = [T] extends [U] ? [U] extends [T] ? true : false : false;
type If<S, T, U> = S extends Falsy ? U : T;

type StrictExtract<T, U> = T extends U ? U extends T ? T : never : never;
type StrictExclude<T, U> = T extends StrictExtract<T, U> ? never : T;

type ExcludeProp<T, V> =
  { [Q in { [P in keyof T]: If<TEq<V, never>, T[P] extends never ? never : P, If<Includes<T[P], V>, never, P>>; }[keyof T]]: T[Q]; };
type DeepExcludeProp<T, V, E extends object | undefined | null = never> =
  T extends E ? T :
  T extends V ? never :
  T extends readonly any[] | Function ? T :
  T extends object ? ExcludeProp<{ [Q in { [P in keyof T]: If<TEq<V, never>, T[P] extends never ? P : P, If<Includes<T[P], V>, T[P] extends E ? P : never, P>>; }[keyof T]]: StrictExclude<DeepExcludeProp<T[Q], V, E>, {}>; }, never> :
  T;
type Includes<T, U> = true extends (T extends U ? true : never) ? true : false;

type AD = { a: boolean; b: { a: boolean; b: boolean[]; c: undefined; d: undefined[]; e: boolean | undefined; f: Array<boolean | undefined>; }; c: { a: undefined; }; };

type a = DeepExcludeProp<AD, undefined, AD['b']>;
type b = ExcludeProp<AD, AD['c']>;
type c = {
  a: boolean;
  b: {
    a: boolean;
    b: boolean[];
    c: undefined;
    d: undefined[];
    e: boolean | undefined;
    f: Array<boolean | undefined>;
  };
};
type d = TEq<a, c>;
type e = TEq<b, c>;
type f = TEq<a, b>;

Expected behavior:

type d = TEq<a, c>; // true
type e = TEq<b, c>; // true
type f = TEq<a, b>; // true

Actual behavior:

type d = TEq<a, c>; // true
type e = TEq<b, c>; // true
type f = TEq<a, b>; // false

Playground Link:

Related Issues: #30047

@falsandtru
Copy link
Contributor Author

@RyanCavanaugh Can you confirm and fix this clear bug you merged?

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Feb 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

3 participants