Merge pull request #21866 from Microsoft/fixIndexedAccessWildcard

Fix indexed access issue with conditional types
This commit is contained in:
Anders Hejlsberg
2018-02-12 14:18:44 -08:00
committed by GitHub
6 changed files with 166 additions and 1 deletions

View File

@@ -7991,7 +7991,7 @@ namespace ts {
}
if (!(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike)) {
if (isTypeAny(objectType)) {
return anyType;
return objectType;
}
const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) ||
getIndexInfoOfType(objectType, IndexKind.String) ||

View File

@@ -436,4 +436,15 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(275,43): error TS
~~~~~
!!! error TS2322: Type 'T95<U>' is not assignable to type 'T94<U>'.
!!! error TS2322: Type 'boolean' is not assignable to type 'true'.
// Repro from #21863
function f50() {
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
type If<S, T, U> = S extends false ? U : T;
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];
type Omit2<T extends object, U = never> = { [P in keyof T]: If<Eq<T[P], U>, never, P>; }[keyof T];
type A = Omit<{ a: void; b: never; }>; // 'a'
type B = Omit2<{ a: void; b: never; }>; // 'a'
}

View File

@@ -274,6 +274,17 @@ type T94<T> = T extends string ? true : 42;
type T95<T> = T extends string ? boolean : number;
const f44 = <U>(value: T94<U>): T95<U> => value;
const f45 = <U>(value: T95<U>): T94<U> => value; // Error
// Repro from #21863
function f50() {
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
type If<S, T, U> = S extends false ? U : T;
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];
type Omit2<T extends object, U = never> = { [P in keyof T]: If<Eq<T[P], U>, never, P>; }[keyof T];
type A = Omit<{ a: void; b: never; }>; // 'a'
type B = Omit2<{ a: void; b: never; }>; // 'a'
}
//// [conditionalTypes1.js]
@@ -361,6 +372,9 @@ var f42 = function (a) { return a; };
var f43 = function (a) { return a; };
var f44 = function (value) { return value; };
var f45 = function (value) { return value; }; // Error
// Repro from #21863
function f50() {
}
//// [conditionalTypes1.d.ts]
@@ -546,3 +560,4 @@ declare type T94<T> = T extends string ? true : 42;
declare type T95<T> = T extends string ? boolean : number;
declare const f44: <U>(value: T94<U>) => T95<U>;
declare const f45: <U>(value: T95<U>) => T94<U>;
declare function f50(): void;

View File

@@ -1059,3 +1059,65 @@ const f45 = <U>(value: T95<U>): T94<U> => value; // Error
>U : Symbol(U, Decl(conditionalTypes1.ts, 274, 13))
>value : Symbol(value, Decl(conditionalTypes1.ts, 274, 16))
// Repro from #21863
function f50() {
>f50 : Symbol(f50, Decl(conditionalTypes1.ts, 274, 48))
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 278, 16))
>T : Symbol(T, Decl(conditionalTypes1.ts, 279, 12))
>U : Symbol(U, Decl(conditionalTypes1.ts, 279, 14))
>T : Symbol(T, Decl(conditionalTypes1.ts, 279, 12))
>U : Symbol(U, Decl(conditionalTypes1.ts, 279, 14))
>U : Symbol(U, Decl(conditionalTypes1.ts, 279, 14))
>T : Symbol(T, Decl(conditionalTypes1.ts, 279, 12))
type If<S, T, U> = S extends false ? U : T;
>If : Symbol(If, Decl(conditionalTypes1.ts, 279, 69))
>S : Symbol(S, Decl(conditionalTypes1.ts, 280, 12))
>T : Symbol(T, Decl(conditionalTypes1.ts, 280, 14))
>U : Symbol(U, Decl(conditionalTypes1.ts, 280, 17))
>S : Symbol(S, Decl(conditionalTypes1.ts, 280, 12))
>U : Symbol(U, Decl(conditionalTypes1.ts, 280, 17))
>T : Symbol(T, Decl(conditionalTypes1.ts, 280, 14))
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];
>Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 280, 47))
>T : Symbol(T, Decl(conditionalTypes1.ts, 281, 14))
>P : Symbol(P, Decl(conditionalTypes1.ts, 281, 37))
>T : Symbol(T, Decl(conditionalTypes1.ts, 281, 14))
>If : Symbol(If, Decl(conditionalTypes1.ts, 279, 69))
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 278, 16))
>T : Symbol(T, Decl(conditionalTypes1.ts, 281, 14))
>P : Symbol(P, Decl(conditionalTypes1.ts, 281, 37))
>P : Symbol(P, Decl(conditionalTypes1.ts, 281, 37))
>T : Symbol(T, Decl(conditionalTypes1.ts, 281, 14))
type Omit2<T extends object, U = never> = { [P in keyof T]: If<Eq<T[P], U>, never, P>; }[keyof T];
>Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 281, 94))
>T : Symbol(T, Decl(conditionalTypes1.ts, 282, 15))
>U : Symbol(U, Decl(conditionalTypes1.ts, 282, 32))
>P : Symbol(P, Decl(conditionalTypes1.ts, 282, 49))
>T : Symbol(T, Decl(conditionalTypes1.ts, 282, 15))
>If : Symbol(If, Decl(conditionalTypes1.ts, 279, 69))
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 278, 16))
>T : Symbol(T, Decl(conditionalTypes1.ts, 282, 15))
>P : Symbol(P, Decl(conditionalTypes1.ts, 282, 49))
>U : Symbol(U, Decl(conditionalTypes1.ts, 282, 32))
>P : Symbol(P, Decl(conditionalTypes1.ts, 282, 49))
>T : Symbol(T, Decl(conditionalTypes1.ts, 282, 15))
type A = Omit<{ a: void; b: never; }>; // 'a'
>A : Symbol(A, Decl(conditionalTypes1.ts, 282, 102))
>Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 280, 47))
>a : Symbol(a, Decl(conditionalTypes1.ts, 283, 19))
>b : Symbol(b, Decl(conditionalTypes1.ts, 283, 28))
type B = Omit2<{ a: void; b: never; }>; // 'a'
>B : Symbol(B, Decl(conditionalTypes1.ts, 283, 42))
>Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 281, 94))
>a : Symbol(a, Decl(conditionalTypes1.ts, 284, 20))
>b : Symbol(b, Decl(conditionalTypes1.ts, 284, 29))
}

View File

@@ -1208,3 +1208,69 @@ const f45 = <U>(value: T95<U>): T94<U> => value; // Error
>U : U
>value : T95<U>
// Repro from #21863
function f50() {
>f50 : () => void
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
>Eq : T extends U ? U extends T ? true : false : false
>T : T
>U : U
>T : T
>U : U
>U : U
>T : T
>true : true
>false : false
>false : false
type If<S, T, U> = S extends false ? U : T;
>If : S extends false ? U : T
>S : S
>T : T
>U : U
>S : S
>false : false
>U : U
>T : T
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];
>Omit : { [P in keyof T]: (T[P] extends never ? boolean : false) extends false ? P : never; }[keyof T]
>T : T
>P : P
>T : T
>If : S extends false ? U : T
>Eq : T extends U ? U extends T ? true : false : false
>T : T
>P : P
>P : P
>T : T
type Omit2<T extends object, U = never> = { [P in keyof T]: If<Eq<T[P], U>, never, P>; }[keyof T];
>Omit2 : { [P in keyof T]: (T[P] extends U ? U extends T[P] ? true : false : false) extends false ? P : never; }[keyof T]
>T : T
>U : U
>P : P
>T : T
>If : S extends false ? U : T
>Eq : T extends U ? U extends T ? true : false : false
>T : T
>P : P
>U : U
>P : P
>T : T
type A = Omit<{ a: void; b: never; }>; // 'a'
>A : "a"
>Omit : { [P in keyof T]: (T[P] extends never ? boolean : false) extends false ? P : never; }[keyof T]
>a : void
>b : never
type B = Omit2<{ a: void; b: never; }>; // 'a'
>B : "a"
>Omit2 : { [P in keyof T]: (T[P] extends U ? U extends T[P] ? true : false : false) extends false ? P : never; }[keyof T]
>a : void
>b : never
}

View File

@@ -276,3 +276,14 @@ type T94<T> = T extends string ? true : 42;
type T95<T> = T extends string ? boolean : number;
const f44 = <U>(value: T94<U>): T95<U> => value;
const f45 = <U>(value: T95<U>): T94<U> => value; // Error
// Repro from #21863
function f50() {
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
type If<S, T, U> = S extends false ? U : T;
type Omit<T extends object> = { [P in keyof T]: If<Eq<T[P], never>, never, P>; }[keyof T];
type Omit2<T extends object, U = never> = { [P in keyof T]: If<Eq<T[P], U>, never, P>; }[keyof T];
type A = Omit<{ a: void; b: never; }>; // 'a'
type B = Omit2<{ a: void; b: never; }>; // 'a'
}