From 081f98232b9ff5c7c7798b807d0a82cf4592f4ca Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 16 Sep 2020 13:31:13 -0700 Subject: [PATCH] Handle the mapping between Array and ReadonlyArray in isTypeDerivedFrom --- src/compiler/checker.ts | 2 +- .../instanceofNarrowReadonlyArray.js | 21 +++++++++++++++++++ .../instanceofNarrowReadonlyArray.symbols | 19 +++++++++++++++++ .../instanceofNarrowReadonlyArray.types | 21 +++++++++++++++++++ .../compiler/instanceofNarrowReadonlyArray.ts | 9 ++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/instanceofNarrowReadonlyArray.js create mode 100644 tests/baselines/reference/instanceofNarrowReadonlyArray.symbols create mode 100644 tests/baselines/reference/instanceofNarrowReadonlyArray.types create mode 100644 tests/cases/compiler/instanceofNarrowReadonlyArray.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a8f6e129f9c..6e80d32111b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15349,7 +15349,7 @@ namespace ts { source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || unknownType, target) : target === globalObjectType ? !!(source.flags & (TypeFlags.Object | TypeFlags.NonPrimitive)) : target === globalFunctionType ? !!(source.flags & TypeFlags.Object) && isFunctionObjectType(source as ObjectType) : - hasBaseType(source, getTargetType(target)); + hasBaseType(source, getTargetType(target)) || (isArrayType(target) && !isReadonlyArrayType(target) && isTypeDerivedFrom(source, globalReadonlyArrayType)); } /** diff --git a/tests/baselines/reference/instanceofNarrowReadonlyArray.js b/tests/baselines/reference/instanceofNarrowReadonlyArray.js new file mode 100644 index 00000000000..a6976ff98f1 --- /dev/null +++ b/tests/baselines/reference/instanceofNarrowReadonlyArray.js @@ -0,0 +1,21 @@ +//// [instanceofNarrowReadonlyArray.ts] +// @strict + +function narrow(x: readonly number[] | number): readonly number[] { + if (x instanceof Array) { + return x; + } else { + return [x]; + } +} + +//// [instanceofNarrowReadonlyArray.js] +// @strict +function narrow(x) { + if (x instanceof Array) { + return x; + } + else { + return [x]; + } +} diff --git a/tests/baselines/reference/instanceofNarrowReadonlyArray.symbols b/tests/baselines/reference/instanceofNarrowReadonlyArray.symbols new file mode 100644 index 00000000000..03d6923f7e2 --- /dev/null +++ b/tests/baselines/reference/instanceofNarrowReadonlyArray.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/instanceofNarrowReadonlyArray.ts === +// @strict + +function narrow(x: readonly number[] | number): readonly number[] { +>narrow : Symbol(narrow, Decl(instanceofNarrowReadonlyArray.ts, 0, 0)) +>x : Symbol(x, Decl(instanceofNarrowReadonlyArray.ts, 2, 16)) + + if (x instanceof Array) { +>x : Symbol(x, Decl(instanceofNarrowReadonlyArray.ts, 2, 16)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + return x; +>x : Symbol(x, Decl(instanceofNarrowReadonlyArray.ts, 2, 16)) + + } else { + return [x]; +>x : Symbol(x, Decl(instanceofNarrowReadonlyArray.ts, 2, 16)) + } +} diff --git a/tests/baselines/reference/instanceofNarrowReadonlyArray.types b/tests/baselines/reference/instanceofNarrowReadonlyArray.types new file mode 100644 index 00000000000..53b4adac41e --- /dev/null +++ b/tests/baselines/reference/instanceofNarrowReadonlyArray.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/instanceofNarrowReadonlyArray.ts === +// @strict + +function narrow(x: readonly number[] | number): readonly number[] { +>narrow : (x: readonly number[] | number) => readonly number[] +>x : number | readonly number[] + + if (x instanceof Array) { +>x instanceof Array : boolean +>x : number | readonly number[] +>Array : ArrayConstructor + + return x; +>x : readonly number[] + + } else { + return [x]; +>[x] : number[] +>x : number + } +} diff --git a/tests/cases/compiler/instanceofNarrowReadonlyArray.ts b/tests/cases/compiler/instanceofNarrowReadonlyArray.ts new file mode 100644 index 00000000000..dbf9d9b409f --- /dev/null +++ b/tests/cases/compiler/instanceofNarrowReadonlyArray.ts @@ -0,0 +1,9 @@ +// @strict + +function narrow(x: readonly number[] | number): readonly number[] { + if (x instanceof Array) { + return x; + } else { + return [x]; + } +} \ No newline at end of file