Skip to content
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

Revert "Merge pull request #27697 from mattmccutchen/issue-27118" #30133

Merged
merged 2 commits into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12724,11 +12724,10 @@ namespace ts {
else if (source.flags & TypeFlags.Conditional) {
if (target.flags & TypeFlags.Conditional) {
// Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if
// they have the same distributivity, T1 and T2 are identical types, U1 and U2 are identical
// types, X1 is related to X2, and Y1 is related to Y2.
if ((<ConditionalType>source).root.isDistributive === (<ConditionalType>target).root.isDistributive &&
isTypeIdenticalTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType) &&
isTypeIdenticalTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType)) {
// one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2,
// and Y1 is related to Y2.
if (isTypeIdenticalTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType) &&
(isRelatedTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType) || isRelatedTo((<ConditionalType>target).checkType, (<ConditionalType>source).checkType))) {
if (result = isRelatedTo(getTrueTypeFromConditionalType(<ConditionalType>source), getTrueTypeFromConditionalType(<ConditionalType>target), reportErrors)) {
result &= isRelatedTo(getFalseTypeFromConditionalType(<ConditionalType>source), getFalseTypeFromConditionalType(<ConditionalType>target), reportErrors);
}
Expand Down
136 changes: 71 additions & 65 deletions tests/baselines/reference/conditionalTypes2.errors.txt
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
tests/cases/conformance/types/conditional/conditionalTypes2.ts(16,5): error TS2322: Type 'Covariant<B>' is not assignable to type 'Covariant<A>'.
Types of property 'foo' are incompatible.
Type 'B extends string ? B : number' is not assignable to type 'A extends string ? A : number'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(17,5): error TS2322: Type 'Covariant<A>' is not assignable to type 'Covariant<B>'.
Types of property 'foo' are incompatible.
Type 'A extends string ? A : number' is not assignable to type 'B extends string ? B : number'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(21,5): error TS2322: Type 'Contravariant<B>' is not assignable to type 'Contravariant<A>'.
Types of property 'foo' are incompatible.
Type 'B extends string ? keyof B : number' is not assignable to type 'A extends string ? keyof A : number'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(22,5): error TS2322: Type 'Contravariant<A>' is not assignable to type 'Contravariant<B>'.
Types of property 'foo' are incompatible.
Type 'A extends string ? keyof A : number' is not assignable to type 'B extends string ? keyof B : number'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(26,5): error TS2322: Type 'Invariant<B>' is not assignable to type 'Invariant<A>'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(15,5): error TS2322: Type 'Covariant<A>' is not assignable to type 'Covariant<B>'.
Type 'A' is not assignable to type 'B'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(19,5): error TS2322: Type 'Contravariant<B>' is not assignable to type 'Contravariant<A>'.
Type 'A' is not assignable to type 'B'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(24,5): error TS2322: Type 'Invariant<B>' is not assignable to type 'Invariant<A>'.
Types of property 'foo' are incompatible.
Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(27,5): error TS2322: Type 'Invariant<A>' is not assignable to type 'Invariant<B>'.
Type 'keyof B' is not assignable to type 'keyof A'.
Type 'string | number | symbol' is not assignable to type 'keyof A'.
Type 'string' is not assignable to type 'keyof A'.
Type 'string' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
Type 'keyof B' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
Type 'string | number | symbol' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
Type 'string' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
Type 'keyof B' is not assignable to type '"valueOf"'.
Type 'string | number | symbol' is not assignable to type '"valueOf"'.
Type 'string' is not assignable to type '"valueOf"'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS2322: Type 'Invariant<A>' is not assignable to type 'Invariant<B>'.
Types of property 'foo' are incompatible.
Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract<Extract<T, Foo>, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
Type 'A' is not assignable to type 'B'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(73,12): error TS2345: Argument of type 'Extract<Extract<T, Foo>, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
Type 'Extract<Foo & T, Bar>' is not assignable to type '{ foo: string; bat: string; }'.
Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(76,12): error TS2345: Argument of type 'Extract<T, Foo & Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(74,12): error TS2345: Argument of type 'Extract<T, Foo & Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
Property 'bat' is missing in type 'Foo & Bar' but required in type '{ foo: string; bat: string; }'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(77,12): error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'.
Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(165,5): error TS2322: Type 'MyElement<A>' is not assignable to type 'MyElement<B>'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(170,5): error TS2322: Type 'MyAcceptor<B>' is not assignable to type 'MyAcceptor<A>'.
tests/cases/conformance/types/conditional/conditionalTypes2.ts(177,5): error TS2322: Type 'Dist<T>' is not assignable to type 'Aux<{ a: T; }>'.


==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (12 errors) ====
// #27118: Conditional types are now invariant in the check type.

==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (7 errors) ====
interface Covariant<T> {
foo: T extends string ? T : number;
}
Expand All @@ -46,29 +44,19 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(177,5): error TS2
}

function f1<A, B extends A>(a: Covariant<A>, b: Covariant<B>) {
a = b; // Error
~
!!! error TS2322: Type 'Covariant<B>' is not assignable to type 'Covariant<A>'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'B extends string ? B : number' is not assignable to type 'A extends string ? A : number'.
a = b;
b = a; // Error
~
!!! error TS2322: Type 'Covariant<A>' is not assignable to type 'Covariant<B>'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'A extends string ? A : number' is not assignable to type 'B extends string ? B : number'.
!!! error TS2322: Type 'A' is not assignable to type 'B'.
}

function f2<A, B extends A>(a: Contravariant<A>, b: Contravariant<B>) {
a = b; // Error
~
!!! error TS2322: Type 'Contravariant<B>' is not assignable to type 'Contravariant<A>'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'B extends string ? keyof B : number' is not assignable to type 'A extends string ? keyof A : number'.
b = a; // Error
~
!!! error TS2322: Type 'Contravariant<A>' is not assignable to type 'Contravariant<B>'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'A extends string ? keyof A : number' is not assignable to type 'B extends string ? keyof B : number'.
!!! error TS2322: Type 'A' is not assignable to type 'B'.
b = a;
}

function f3<A, B extends A>(a: Invariant<A>, b: Invariant<B>) {
Expand All @@ -77,11 +65,22 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(177,5): error TS2
!!! error TS2322: Type 'Invariant<B>' is not assignable to type 'Invariant<A>'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'.
!!! error TS2322: Type 'keyof B' is not assignable to type 'keyof A'.
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof A'.
!!! error TS2322: Type 'string' is not assignable to type 'keyof A'.
!!! error TS2322: Type 'string' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
!!! error TS2322: Type 'keyof B' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
!!! error TS2322: Type 'string' is not assignable to type 'number | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "length" | "substr" | "valueOf"'.
!!! error TS2322: Type 'keyof B' is not assignable to type '"valueOf"'.
!!! error TS2322: Type 'string | number | symbol' is not assignable to type '"valueOf"'.
!!! error TS2322: Type 'string' is not assignable to type '"valueOf"'.
b = a; // Error
~
!!! error TS2322: Type 'Invariant<A>' is not assignable to type 'Invariant<B>'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'.
!!! error TS2322: Type 'A' is not assignable to type 'B'.
}

// Extract<T, Function> is a T that is known to be a Function
Expand Down Expand Up @@ -135,20 +134,52 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(177,5): error TS2
!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
!!! error TS2345: Type 'Extract<Foo & T, Bar>' is not assignable to type '{ foo: string; bat: string; }'.
!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:64:43: 'bat' is declared here.
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:64:43: 'bat' is declared here.
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
fooBat(y); // Error
~
!!! error TS2345: Argument of type 'Extract<T, Foo & Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
!!! error TS2345: Property 'bat' is missing in type 'Foo & Bar' but required in type '{ foo: string; bat: string; }'.
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:64:43: 'bat' is declared here.
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
fooBat(z); // Error
~
!!! error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
!!! error TS2345: Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'.
!!! error TS2345: Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'.
}

// Repros from #22860

class Opt<T> {
toVector(): Vector<T> {
return <any>undefined;
}
}

interface Seq<T> {
tail(): Opt<Seq<T>>;
}

class Vector<T> implements Seq<T> {
tail(): Opt<Vector<T>> {
return <any>undefined;
}
partition2<U extends T>(predicate:(v:T)=>v is U): [Vector<U>,Vector<Exclude<T, U>>];
partition2(predicate:(x:T)=>boolean): [Vector<T>,Vector<T>];
partition2<U extends T>(predicate:(v:T)=>boolean): [Vector<U>,Vector<any>] {
return <any>undefined;
}
}

interface A1<T> {
bat: B1<A1<T>>;
}

interface B1<T> extends A1<T> {
bat: B1<B1<T>>;
boom: T extends any ? true : true
}

// Repro from #22899

declare function toString1(value: object | Function): string ;
Expand Down Expand Up @@ -229,29 +260,4 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(177,5): error TS2
};
type PCCA = ProductComplementComplement['a'];
type PCCB = ProductComplementComplement['b'];

// Repros from #27118

type MyElement<A> = [A] extends [[infer E]] ? E : never;
function oops<A, B extends A>(arg: MyElement<A>): MyElement<B> {
return arg; // Unsound, should be error
~~~~~~~~~~~
!!! error TS2322: Type 'MyElement<A>' is not assignable to type 'MyElement<B>'.
}

type MyAcceptor<A> = [A] extends [[infer E]] ? (arg: E) => void : never;
function oops2<A, B extends A>(arg: MyAcceptor<B>): MyAcceptor<A> {
return arg; // Unsound, should be error
~~~~~~~~~~~
!!! error TS2322: Type 'MyAcceptor<B>' is not assignable to type 'MyAcceptor<A>'.
}

type Dist<T> = T extends number ? number : string;
type Aux<A extends { a: unknown }> = A["a"] extends number ? number : string;
type Nondist<T> = Aux<{a: T}>;
function oops3<T>(arg: Dist<T>): Nondist<T> {
return arg; // Unsound, should be error
~~~~~~~~~~~
!!! error TS2322: Type 'Dist<T>' is not assignable to type 'Aux<{ a: T; }>'.
}

Loading