// @strictNullChecks: true
// Repro from #8513
let cond: boolean;
export type Optional = Some | None;
export interface None { readonly none: string; }
export interface Some { readonly some: a; }
export const none : None = { none: '' };
export function isSome(value: Optional): value is Some {
return 'some' in value;
}
function someFrom(some: a) {
return { some };
}
export function fn(makeSome: () => r): void {
let result: Optional = none;
result; // None
while (cond) {
result; // Some | None
result = someFrom(isSome(result) ? result.some : makeSome());
result; // Some
}
}
function foo1() {
let x: string | number | boolean = 0;
x; // number
while (cond) {
x; // number, then string | number
x = typeof x === "string" ? x.slice() : "abc";
x; // string
}
x;
}
function foo2() {
let x: string | number | boolean = 0;
x; // number
while (cond) {
x; // number, then string | number
if (typeof x === "string") {
x = x.slice();
}
else {
x = "abc";
}
x; // string
}
x;
}
// Type guards as assertions
function f1() {
let x: string | number | undefined = undefined;
x; // undefined
if (x) {
x; // string | number (guard as assertion)
}
x; // string | number | undefined
}
function f2() {
let x: string | number | undefined = undefined;
x; // undefined
if (typeof x === "string") {
x; // string (guard as assertion)
}
x; // string | undefined
}
function f3() {
let x: string | number | undefined = undefined;
x; // undefined
if (!x) {
return;
}
x; // string | number (guard as assertion)
}
function f4() {
let x: string | number | undefined = undefined;
x; // undefined
if (typeof x === "boolean") {
x; // nothing (boolean not in declared type)
}
x; // undefined
}
function f5(x: string | number) {
if (typeof x === "string" && typeof x === "number") {
x; // number (guard as assertion)
}
else {
x; // string | number
}
x; // string | number
}
function f6() {
let x: string | undefined | null;
x!.slice();
x = "";
x!.slice();
x = undefined;
x!.slice();
x = null;
x!.slice();
x = undefined;
x!.slice();
x = "";
x!.slice();
x = "";
x!.slice();
}
function f7() {
let x: string;
x!.slice();
}