From 34eb5ddf75ad7401217175a4d623d34e9aaee534 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 25 Jun 2019 20:56:41 -0700 Subject: [PATCH] Fix tuple and array comparisons during identity checking (#32089) --- src/compiler/checker.ts | 9 ++++++++- ...uickinfoExpressionTypeNotChangedViaDeletion.ts | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/quickinfoExpressionTypeNotChangedViaDeletion.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a3abe1dc5b5..fb96ca0813a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13321,7 +13321,14 @@ namespace ts { } } else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { - return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors); + if (relation !== identityRelation) { + return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors); + } + else { + // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple + // or `target` is an array and source is a tuple - in both cases the types cannot be identical, by construction + return Ternary.False; + } } // Consider a fresh empty object literal type "closed" under the subtype relationship - this way `{} <- {[idx: string]: any} <- fresh({})` // and not `{} <- fresh({}) <- {[idx: string]: any}` diff --git a/tests/cases/fourslash/quickinfoExpressionTypeNotChangedViaDeletion.ts b/tests/cases/fourslash/quickinfoExpressionTypeNotChangedViaDeletion.ts new file mode 100644 index 00000000000..01656aea566 --- /dev/null +++ b/tests/cases/fourslash/quickinfoExpressionTypeNotChangedViaDeletion.ts @@ -0,0 +1,15 @@ +/// +////type TypeEq = (() => T extends A ? 1 : 2) extends (() => T extends B ? 1 : 2) ? true : false; +//// +////const /*2*/test1: TypeEq = false; +//// +////declare const foo: [number, ...number[]]; +////declare const bar: number[]; +//// +////const /*1*/test2: TypeEq = false; + +goTo.marker("1"); +verify.quickInfoIs("const test2: false"); + +goTo.marker("2"); +verify.quickInfoIs("const test1: false");