3d6650eb4f
* Fix #38608 * Work for narrowed non-unions * Add comment
334 lines
6.3 KiB
TypeScript
334 lines
6.3 KiB
TypeScript
//// [inKeywordTypeguard.ts]
|
|
class A { a: string; }
|
|
class B { b: string; }
|
|
|
|
function negativeClassesTest(x: A | B) {
|
|
if ("a" in x) {
|
|
x.b = "1";
|
|
} else {
|
|
x.a = "1";
|
|
}
|
|
}
|
|
|
|
function positiveClassesTest(x: A | B) {
|
|
if ("a" in x) {
|
|
x.b = "1";
|
|
} else {
|
|
x.a = "1";
|
|
}
|
|
}
|
|
|
|
class AWithOptionalProp { a?: string; }
|
|
class BWithOptionalProp { b?: string; }
|
|
|
|
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
|
if ("a" in x) {
|
|
x.a = "1";
|
|
} else {
|
|
x.b = "1";
|
|
}
|
|
}
|
|
|
|
class AWithMethod {
|
|
a(): string { return ""; }
|
|
}
|
|
|
|
class BWithMethod {
|
|
b(): string { return ""; }
|
|
}
|
|
|
|
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
|
|
if ("a" in x) {
|
|
x.a();
|
|
x.b();
|
|
} else {
|
|
}
|
|
}
|
|
|
|
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
|
|
if ("c" in x) {
|
|
x.a();
|
|
x.b();
|
|
} else {
|
|
x.a();
|
|
x.b();
|
|
}
|
|
}
|
|
|
|
class C { a: string; }
|
|
class D { a: string; }
|
|
|
|
function negativeMultipleClassesTest(x: A | B | C | D) {
|
|
if ("a" in x) {
|
|
x.b = "1";
|
|
} else {
|
|
x.a = "1";
|
|
}
|
|
}
|
|
|
|
class ClassWithUnionProp { prop: A | B }
|
|
|
|
function negativePropTest(x: ClassWithUnionProp) {
|
|
if ("a" in x.prop) {
|
|
let y: string = x.prop.b;
|
|
} else {
|
|
let z: string = x.prop.a;
|
|
}
|
|
}
|
|
|
|
class NegativeClassTest {
|
|
protected prop: A | B;
|
|
inThis() {
|
|
if ("a" in this.prop) {
|
|
let z: number = this.prop.b;
|
|
} else {
|
|
let y: string = this.prop.a;
|
|
}
|
|
}
|
|
}
|
|
|
|
class UnreachableCodeDetection {
|
|
a: string;
|
|
inThis() {
|
|
if ("a" in this) {
|
|
} else {
|
|
let y = this.a;
|
|
}
|
|
}
|
|
}
|
|
|
|
function positiveIntersectionTest(x: { a: string } & { b: string }) {
|
|
if ("a" in x) {
|
|
let s: string = x.a;
|
|
} else {
|
|
let n: never = x;
|
|
}
|
|
}
|
|
|
|
// Repro from #38608
|
|
declare const error: Error;
|
|
if ('extra' in error) {
|
|
error // Still Error
|
|
} else {
|
|
error // Error
|
|
}
|
|
|
|
function narrowsToNever(x: { l: number } | { r: number }) {
|
|
let v: number;
|
|
if ("l" in x) {
|
|
v = x.l;
|
|
}
|
|
else if ("r" in x) {
|
|
v = x.r;
|
|
}
|
|
else {
|
|
v = x
|
|
}
|
|
return v;
|
|
}
|
|
|
|
type AOrB = { aProp: number } | { bProp: number };
|
|
declare function isAOrB(x: unknown): x is AOrB;
|
|
|
|
declare var x: unknown;
|
|
if (isAOrB(x)) {
|
|
if ("aProp" in x) {
|
|
x.aProp;
|
|
}
|
|
else if ("bProp" in x) {
|
|
x.bProp;
|
|
}
|
|
// x is never because of the type predicate from unknown
|
|
else if ("cProp" in x) {
|
|
const _never: never = x;
|
|
}
|
|
}
|
|
|
|
function negativeIntersectionTest() {
|
|
if ("ontouchstart" in window) {
|
|
window.ontouchstart
|
|
} else {
|
|
window.ontouchstart
|
|
}
|
|
}
|
|
|
|
|
|
//// [inKeywordTypeguard.js]
|
|
var A = /** @class */ (function () {
|
|
function A() {
|
|
}
|
|
return A;
|
|
}());
|
|
var B = /** @class */ (function () {
|
|
function B() {
|
|
}
|
|
return B;
|
|
}());
|
|
function negativeClassesTest(x) {
|
|
if ("a" in x) {
|
|
x.b = "1";
|
|
}
|
|
else {
|
|
x.a = "1";
|
|
}
|
|
}
|
|
function positiveClassesTest(x) {
|
|
if ("a" in x) {
|
|
x.b = "1";
|
|
}
|
|
else {
|
|
x.a = "1";
|
|
}
|
|
}
|
|
var AWithOptionalProp = /** @class */ (function () {
|
|
function AWithOptionalProp() {
|
|
}
|
|
return AWithOptionalProp;
|
|
}());
|
|
var BWithOptionalProp = /** @class */ (function () {
|
|
function BWithOptionalProp() {
|
|
}
|
|
return BWithOptionalProp;
|
|
}());
|
|
function positiveTestClassesWithOptionalProperties(x) {
|
|
if ("a" in x) {
|
|
x.a = "1";
|
|
}
|
|
else {
|
|
x.b = "1";
|
|
}
|
|
}
|
|
var AWithMethod = /** @class */ (function () {
|
|
function AWithMethod() {
|
|
}
|
|
AWithMethod.prototype.a = function () { return ""; };
|
|
return AWithMethod;
|
|
}());
|
|
var BWithMethod = /** @class */ (function () {
|
|
function BWithMethod() {
|
|
}
|
|
BWithMethod.prototype.b = function () { return ""; };
|
|
return BWithMethod;
|
|
}());
|
|
function negativeTestClassesWithMembers(x) {
|
|
if ("a" in x) {
|
|
x.a();
|
|
x.b();
|
|
}
|
|
else {
|
|
}
|
|
}
|
|
function negativeTestClassesWithMemberMissingInBothClasses(x) {
|
|
if ("c" in x) {
|
|
x.a();
|
|
x.b();
|
|
}
|
|
else {
|
|
x.a();
|
|
x.b();
|
|
}
|
|
}
|
|
var C = /** @class */ (function () {
|
|
function C() {
|
|
}
|
|
return C;
|
|
}());
|
|
var D = /** @class */ (function () {
|
|
function D() {
|
|
}
|
|
return D;
|
|
}());
|
|
function negativeMultipleClassesTest(x) {
|
|
if ("a" in x) {
|
|
x.b = "1";
|
|
}
|
|
else {
|
|
x.a = "1";
|
|
}
|
|
}
|
|
var ClassWithUnionProp = /** @class */ (function () {
|
|
function ClassWithUnionProp() {
|
|
}
|
|
return ClassWithUnionProp;
|
|
}());
|
|
function negativePropTest(x) {
|
|
if ("a" in x.prop) {
|
|
var y = x.prop.b;
|
|
}
|
|
else {
|
|
var z = x.prop.a;
|
|
}
|
|
}
|
|
var NegativeClassTest = /** @class */ (function () {
|
|
function NegativeClassTest() {
|
|
}
|
|
NegativeClassTest.prototype.inThis = function () {
|
|
if ("a" in this.prop) {
|
|
var z = this.prop.b;
|
|
}
|
|
else {
|
|
var y = this.prop.a;
|
|
}
|
|
};
|
|
return NegativeClassTest;
|
|
}());
|
|
var UnreachableCodeDetection = /** @class */ (function () {
|
|
function UnreachableCodeDetection() {
|
|
}
|
|
UnreachableCodeDetection.prototype.inThis = function () {
|
|
if ("a" in this) {
|
|
}
|
|
else {
|
|
var y = this.a;
|
|
}
|
|
};
|
|
return UnreachableCodeDetection;
|
|
}());
|
|
function positiveIntersectionTest(x) {
|
|
if ("a" in x) {
|
|
var s = x.a;
|
|
}
|
|
else {
|
|
var n = x;
|
|
}
|
|
}
|
|
if ('extra' in error) {
|
|
error; // Still Error
|
|
}
|
|
else {
|
|
error; // Error
|
|
}
|
|
function narrowsToNever(x) {
|
|
var v;
|
|
if ("l" in x) {
|
|
v = x.l;
|
|
}
|
|
else if ("r" in x) {
|
|
v = x.r;
|
|
}
|
|
else {
|
|
v = x;
|
|
}
|
|
return v;
|
|
}
|
|
if (isAOrB(x)) {
|
|
if ("aProp" in x) {
|
|
x.aProp;
|
|
}
|
|
else if ("bProp" in x) {
|
|
x.bProp;
|
|
}
|
|
// x is never because of the type predicate from unknown
|
|
else if ("cProp" in x) {
|
|
var _never = x;
|
|
}
|
|
}
|
|
function negativeIntersectionTest() {
|
|
if ("ontouchstart" in window) {
|
|
window.ontouchstart;
|
|
}
|
|
else {
|
|
window.ontouchstart;
|
|
}
|
|
}
|