Cherry-pick PR #38398 into release-3.9 (#38400)

Component commits:
99c5c096c5 Properly finalize evolving array type in getTypeAtFlowCall

b355cd4da4 Add regression test

Co-authored-by: Anders Hejlsberg <andersh@microsoft.com>
This commit is contained in:
TypeScript Bot 2020-05-07 23:50:20 -07:00 committed by GitHub
parent 8f79cd42f4
commit d906a471dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 1 deletions

View File

@ -20291,7 +20291,7 @@ namespace ts {
const predicate = getTypePredicateOfSignature(signature);
if (predicate && (predicate.kind === TypePredicateKind.AssertsThis || predicate.kind === TypePredicateKind.AssertsIdentifier)) {
const flowType = getTypeAtFlowNode(flow.antecedent);
const type = getTypeFromFlowType(flowType);
const type = finalizeEvolvingArrayType(getTypeFromFlowType(flowType));
const narrowedType = predicate.type ? narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) :
predicate.kind === TypePredicateKind.AssertsIdentifier && predicate.parameterIndex >= 0 && predicate.parameterIndex < flow.node.arguments.length ? narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]) :
type;

View File

@ -0,0 +1,23 @@
//// [evolvingArrayTypeInAssert.ts]
export function unsafeCast<T>(_value: unknown): asserts _value is T { }
function yadda() {
let out = [];
out.push(100)
unsafeCast<any>(out);
return out;
}
//// [evolvingArrayTypeInAssert.js]
"use strict";
exports.__esModule = true;
exports.unsafeCast = void 0;
function unsafeCast(_value) { }
exports.unsafeCast = unsafeCast;
function yadda() {
var out = [];
out.push(100);
unsafeCast(out);
return out;
}

View File

@ -0,0 +1,27 @@
=== tests/cases/compiler/evolvingArrayTypeInAssert.ts ===
export function unsafeCast<T>(_value: unknown): asserts _value is T { }
>unsafeCast : Symbol(unsafeCast, Decl(evolvingArrayTypeInAssert.ts, 0, 0))
>T : Symbol(T, Decl(evolvingArrayTypeInAssert.ts, 0, 27))
>_value : Symbol(_value, Decl(evolvingArrayTypeInAssert.ts, 0, 30))
>_value : Symbol(_value, Decl(evolvingArrayTypeInAssert.ts, 0, 30))
>T : Symbol(T, Decl(evolvingArrayTypeInAssert.ts, 0, 27))
function yadda() {
>yadda : Symbol(yadda, Decl(evolvingArrayTypeInAssert.ts, 0, 71))
let out = [];
>out : Symbol(out, Decl(evolvingArrayTypeInAssert.ts, 3, 7))
out.push(100)
>out.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>out : Symbol(out, Decl(evolvingArrayTypeInAssert.ts, 3, 7))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
unsafeCast<any>(out);
>unsafeCast : Symbol(unsafeCast, Decl(evolvingArrayTypeInAssert.ts, 0, 0))
>out : Symbol(out, Decl(evolvingArrayTypeInAssert.ts, 3, 7))
return out;
>out : Symbol(out, Decl(evolvingArrayTypeInAssert.ts, 3, 7))
}

View File

@ -0,0 +1,28 @@
=== tests/cases/compiler/evolvingArrayTypeInAssert.ts ===
export function unsafeCast<T>(_value: unknown): asserts _value is T { }
>unsafeCast : <T>(_value: unknown) => asserts _value is T
>_value : unknown
function yadda() {
>yadda : () => number[]
let out = [];
>out : any[]
>[] : never[]
out.push(100)
>out.push(100) : number
>out.push : (...items: any[]) => number
>out : any[]
>push : (...items: any[]) => number
>100 : 100
unsafeCast<any>(out);
>unsafeCast<any>(out) : void
>unsafeCast : <T>(_value: unknown) => asserts _value is T
>out : number[]
return out;
>out : number[]
}

View File

@ -0,0 +1,10 @@
// @strict: true
export function unsafeCast<T>(_value: unknown): asserts _value is T { }
function yadda() {
let out = [];
out.push(100)
unsafeCast<any>(out);
return out;
}