* Fix #10083 - allowSyntheticDefaultImports alters getExternalModuleMember (#10096) * Add a helper function `getOrUpdateProperty` to prevent unprotected access to Maps. * Limit type guards as assertions to incomplete types in loops * Accept new baselines * Fix linting error * [Release-2.0] Fix 9662: Visual Studio 2015 with TS2.0 gives incorrect @types path resolution errors (#9867) * Change the shape of the shim layer to support getAutomaticTypeDirectives * Change the key for looking up automatic type-directives * Update baselines from change look-up name of type-directives * Add @currentDirectory into the test * Update baselines * Fix linting error * Address PR: fix spelling mistake * Instead of return path of the type directive names just return type directive names * Remove unused reference files: these tests produce erros so they will not produce these files (#9233) * Don't allow properties inherited from Object to be automatically included in TSX attributes * Port PR #10016 to Master (#10100) * Treat namespaceExportDeclaration as declaration * Update baselines * wip - add tests * Add tests * Show "export namespace" for quick-info * Update baselines from merging
386 lines
8.3 KiB
Plaintext
386 lines
8.3 KiB
Plaintext
=== tests/cases/conformance/controlFlow/typeGuardsAsAssertions.ts ===
|
|
|
|
// Repro from #8513
|
|
|
|
let cond: boolean;
|
|
>cond : boolean
|
|
|
|
export type Optional<a> = Some<a> | None;
|
|
>Optional : Optional<a>
|
|
>a : a
|
|
>Some : Some<a>
|
|
>a : a
|
|
>None : None
|
|
|
|
export interface None { readonly none: string; }
|
|
>None : None
|
|
>none : string
|
|
|
|
export interface Some<a> { readonly some: a; }
|
|
>Some : Some<a>
|
|
>a : a
|
|
>some : a
|
|
>a : a
|
|
|
|
export const none : None = { none: '' };
|
|
>none : None
|
|
>None : None
|
|
>{ none: '' } : { none: string; }
|
|
>none : string
|
|
>'' : string
|
|
|
|
export function isSome<a>(value: Optional<a>): value is Some<a> {
|
|
>isSome : <a>(value: Optional<a>) => value is Some<a>
|
|
>a : a
|
|
>value : Optional<a>
|
|
>Optional : Optional<a>
|
|
>a : a
|
|
>value : any
|
|
>Some : Some<a>
|
|
>a : a
|
|
|
|
return 'some' in value;
|
|
>'some' in value : boolean
|
|
>'some' : string
|
|
>value : Optional<a>
|
|
}
|
|
|
|
function someFrom<a>(some: a) {
|
|
>someFrom : <a>(some: a) => { some: a; }
|
|
>a : a
|
|
>some : a
|
|
>a : a
|
|
|
|
return { some };
|
|
>{ some } : { some: a; }
|
|
>some : a
|
|
}
|
|
|
|
export function fn<r>(makeSome: () => r): void {
|
|
>fn : <r>(makeSome: () => r) => void
|
|
>r : r
|
|
>makeSome : () => r
|
|
>r : r
|
|
|
|
let result: Optional<r> = none;
|
|
>result : Optional<r>
|
|
>Optional : Optional<a>
|
|
>r : r
|
|
>none : None
|
|
|
|
result; // None
|
|
>result : None
|
|
|
|
while (cond) {
|
|
>cond : boolean
|
|
|
|
result; // Some<r> | None
|
|
>result : Optional<r>
|
|
|
|
result = someFrom(isSome(result) ? result.some : makeSome());
|
|
>result = someFrom(isSome(result) ? result.some : makeSome()) : { some: r; }
|
|
>result : Optional<r>
|
|
>someFrom(isSome(result) ? result.some : makeSome()) : { some: r; }
|
|
>someFrom : <a>(some: a) => { some: a; }
|
|
>isSome(result) ? result.some : makeSome() : r
|
|
>isSome(result) : boolean
|
|
>isSome : <a>(value: Optional<a>) => value is Some<a>
|
|
>result : Optional<r>
|
|
>result.some : r
|
|
>result : Some<r>
|
|
>some : r
|
|
>makeSome() : r
|
|
>makeSome : () => r
|
|
|
|
result; // Some<r>
|
|
>result : Some<r>
|
|
}
|
|
}
|
|
|
|
function foo1() {
|
|
>foo1 : () => void
|
|
|
|
let x: string | number | boolean = 0;
|
|
>x : string | number | boolean
|
|
>0 : number
|
|
|
|
x; // number
|
|
>x : number
|
|
|
|
while (cond) {
|
|
>cond : boolean
|
|
|
|
x; // number, then string | number
|
|
>x : string | number
|
|
|
|
x = typeof x === "string" ? x.slice() : "abc";
|
|
>x = typeof x === "string" ? x.slice() : "abc" : string
|
|
>x : string | number | boolean
|
|
>typeof x === "string" ? x.slice() : "abc" : string
|
|
>typeof x === "string" : boolean
|
|
>typeof x : string
|
|
>x : string | number
|
|
>"string" : "string"
|
|
>x.slice() : string
|
|
>x.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x : string
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>"abc" : string
|
|
|
|
x; // string
|
|
>x : string
|
|
}
|
|
x;
|
|
>x : string | number
|
|
}
|
|
|
|
function foo2() {
|
|
>foo2 : () => void
|
|
|
|
let x: string | number | boolean = 0;
|
|
>x : string | number | boolean
|
|
>0 : number
|
|
|
|
x; // number
|
|
>x : number
|
|
|
|
while (cond) {
|
|
>cond : boolean
|
|
|
|
x; // number, then string | number
|
|
>x : string | number
|
|
|
|
if (typeof x === "string") {
|
|
>typeof x === "string" : boolean
|
|
>typeof x : string
|
|
>x : string | number
|
|
>"string" : "string"
|
|
|
|
x = x.slice();
|
|
>x = x.slice() : string
|
|
>x : string | number | boolean
|
|
>x.slice() : string
|
|
>x.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x : string
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
}
|
|
else {
|
|
x = "abc";
|
|
>x = "abc" : string
|
|
>x : string | number | boolean
|
|
>"abc" : string
|
|
}
|
|
x; // string
|
|
>x : string
|
|
}
|
|
x;
|
|
>x : string | number
|
|
}
|
|
|
|
// Type guards as assertions
|
|
|
|
function f1() {
|
|
>f1 : () => void
|
|
|
|
let x: string | number | undefined = undefined;
|
|
>x : string | number | undefined
|
|
>undefined : undefined
|
|
|
|
x; // undefined
|
|
>x : undefined
|
|
|
|
if (x) {
|
|
>x : undefined
|
|
|
|
x; // string | number (guard as assertion)
|
|
>x : never
|
|
}
|
|
x; // string | number | undefined
|
|
>x : undefined
|
|
}
|
|
|
|
function f2() {
|
|
>f2 : () => void
|
|
|
|
let x: string | number | undefined = undefined;
|
|
>x : string | number | undefined
|
|
>undefined : undefined
|
|
|
|
x; // undefined
|
|
>x : undefined
|
|
|
|
if (typeof x === "string") {
|
|
>typeof x === "string" : boolean
|
|
>typeof x : string
|
|
>x : undefined
|
|
>"string" : "string"
|
|
|
|
x; // string (guard as assertion)
|
|
>x : never
|
|
}
|
|
x; // string | undefined
|
|
>x : undefined
|
|
}
|
|
|
|
function f3() {
|
|
>f3 : () => void
|
|
|
|
let x: string | number | undefined = undefined;
|
|
>x : string | number | undefined
|
|
>undefined : undefined
|
|
|
|
x; // undefined
|
|
>x : undefined
|
|
|
|
if (!x) {
|
|
>!x : true
|
|
>x : undefined
|
|
|
|
return;
|
|
}
|
|
x; // string | number (guard as assertion)
|
|
>x : never
|
|
}
|
|
|
|
function f4() {
|
|
>f4 : () => void
|
|
|
|
let x: string | number | undefined = undefined;
|
|
>x : string | number | undefined
|
|
>undefined : undefined
|
|
|
|
x; // undefined
|
|
>x : undefined
|
|
|
|
if (typeof x === "boolean") {
|
|
>typeof x === "boolean" : boolean
|
|
>typeof x : string
|
|
>x : undefined
|
|
>"boolean" : "boolean"
|
|
|
|
x; // nothing (boolean not in declared type)
|
|
>x : never
|
|
}
|
|
x; // undefined
|
|
>x : undefined
|
|
}
|
|
|
|
function f5(x: string | number) {
|
|
>f5 : (x: string | number) => void
|
|
>x : string | number
|
|
|
|
if (typeof x === "string" && typeof x === "number") {
|
|
>typeof x === "string" && typeof x === "number" : boolean
|
|
>typeof x === "string" : boolean
|
|
>typeof x : string
|
|
>x : string | number
|
|
>"string" : "string"
|
|
>typeof x === "number" : boolean
|
|
>typeof x : string
|
|
>x : string
|
|
>"number" : "number"
|
|
|
|
x; // number (guard as assertion)
|
|
>x : never
|
|
}
|
|
else {
|
|
x; // string | number
|
|
>x : string | number
|
|
}
|
|
x; // string | number
|
|
>x : string | number
|
|
}
|
|
|
|
function f6() {
|
|
>f6 : () => void
|
|
|
|
let x: string | undefined | null;
|
|
>x : string | null | undefined
|
|
>null : null
|
|
|
|
x!.slice();
|
|
>x!.slice() : string
|
|
>x!.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x! : string
|
|
>x : string | null | undefined
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
|
|
x = "";
|
|
>x = "" : string
|
|
>x : string | null | undefined
|
|
>"" : string
|
|
|
|
x!.slice();
|
|
>x!.slice() : string
|
|
>x!.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x! : string
|
|
>x : string
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
|
|
x = undefined;
|
|
>x = undefined : undefined
|
|
>x : string | null | undefined
|
|
>undefined : undefined
|
|
|
|
x!.slice();
|
|
>x!.slice() : string
|
|
>x!.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x! : string
|
|
>x : string | null | undefined
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
|
|
x = null;
|
|
>x = null : null
|
|
>x : string | null | undefined
|
|
>null : null
|
|
|
|
x!.slice();
|
|
>x!.slice() : string
|
|
>x!.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x! : string
|
|
>x : string | null | undefined
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
|
|
x = <undefined | null>undefined;
|
|
>x = <undefined | null>undefined : null | undefined
|
|
>x : string | null | undefined
|
|
><undefined | null>undefined : null | undefined
|
|
>null : null
|
|
>undefined : undefined
|
|
|
|
x!.slice();
|
|
>x!.slice() : string
|
|
>x!.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x! : string
|
|
>x : string | null | undefined
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
|
|
x = <string | undefined>"";
|
|
>x = <string | undefined>"" : string | undefined
|
|
>x : string | null | undefined
|
|
><string | undefined>"" : string | undefined
|
|
>"" : string
|
|
|
|
x!.slice();
|
|
>x!.slice() : string
|
|
>x!.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x! : string
|
|
>x : string | undefined
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
|
|
x = <string | null>"";
|
|
>x = <string | null>"" : string | null
|
|
>x : string | null | undefined
|
|
><string | null>"" : string | null
|
|
>null : null
|
|
>"" : string
|
|
|
|
x!.slice();
|
|
>x!.slice() : string
|
|
>x!.slice : (start?: number | undefined, end?: number | undefined) => string
|
|
>x! : string
|
|
>x : string | null
|
|
>slice : (start?: number | undefined, end?: number | undefined) => string
|
|
}
|
|
|