diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 76bd39a00bf..649a591b891 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -8386,7 +8386,7 @@ namespace ts {
// - In a static member function or static member accessor
// where this references the constructor function object of a derived class,
// a super property access is permitted and must specify a public static member function of the base class.
- if (getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
+ if (languageVersion < ScriptTarget.ES6 && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) {
// `prop` refers to a *property* declared in the super class
// rather than a *method*, so it does not satisfy the above criteria.
@@ -14295,7 +14295,7 @@ namespace ts {
}
const { declarations, flags } = exports[id];
// ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces)
- if (!(flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) && declarations.length > 1) {
+ if (!(flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) && (flags & SymbolFlags.TypeAlias ? declarations.length - 1 : declarations.length) > 1) {
const exportedDeclarations: Declaration[] = filter(declarations, isNotOverload);
if (exportedDeclarations.length > 1) {
for (const declaration of exportedDeclarations) {
diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts
index 61accfb71af..836b2daeab2 100644
--- a/src/compiler/sys.ts
+++ b/src/compiler/sys.ts
@@ -51,6 +51,8 @@ namespace ts {
args: string[];
currentDirectory: string;
executingFile: string;
+ newLine?: string;
+ useCaseSensitiveFileNames?: boolean;
echo(s: string): void;
quit(exitCode?: number): void;
fileExists(path: string): boolean;
@@ -60,6 +62,8 @@ namespace ts {
readFile(path: string): string;
writeFile(path: string, contents: string): void;
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
+ watchFile?(path: string, callback: (path: string, removed?: boolean) => void): FileWatcher;
+ watchDirectory?(path: string, callback: (path: string) => void, recursive?: boolean): FileWatcher;
};
export var sys: System = (function () {
@@ -469,9 +473,9 @@ namespace ts {
function getChakraSystem(): System {
return {
- newLine: "\r\n",
+ newLine: ChakraHost.newLine || "\r\n",
args: ChakraHost.args,
- useCaseSensitiveFileNames: false,
+ useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames,
write: ChakraHost.echo,
readFile(path: string, encoding?: string) {
// encoding is automatically handled by the implementation in ChakraHost
diff --git a/tests/baselines/reference/superPropertyAccess_ES5.errors.txt b/tests/baselines/reference/superPropertyAccess_ES5.errors.txt
new file mode 100644
index 00000000000..08adcd36e68
--- /dev/null
+++ b/tests/baselines/reference/superPropertyAccess_ES5.errors.txt
@@ -0,0 +1,38 @@
+tests/cases/compiler/superPropertyAccess_ES5.ts(12,22): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.
+tests/cases/compiler/superPropertyAccess_ES5.ts(27,15): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.
+
+
+==== tests/cases/compiler/superPropertyAccess_ES5.ts (2 errors) ====
+
+ class MyBase {
+ getValue(): number { return 1; }
+ get value(): number { return 1; }
+ }
+
+ class MyDerived extends MyBase {
+ constructor() {
+ super();
+
+ const f1 = super.getValue();
+ const f2 = super.value;
+ ~~~~~
+!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.
+ }
+ }
+
+ var d = new MyDerived();
+ var f3 = d.value;
+
+ class A {
+ private _property: string;
+ get property() { return this._property; }
+ set property(value: string) { this._property = value }
+ }
+
+ class B extends A {
+ set property(value: string) {
+ super.property = value + " addition";
+ ~~~~~~~~
+!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.
+ }
+ }
\ No newline at end of file
diff --git a/tests/baselines/reference/superPropertyAccess_ES5.js b/tests/baselines/reference/superPropertyAccess_ES5.js
new file mode 100644
index 00000000000..63f5f6f316a
--- /dev/null
+++ b/tests/baselines/reference/superPropertyAccess_ES5.js
@@ -0,0 +1,84 @@
+//// [superPropertyAccess_ES5.ts]
+
+class MyBase {
+ getValue(): number { return 1; }
+ get value(): number { return 1; }
+}
+
+class MyDerived extends MyBase {
+ constructor() {
+ super();
+
+ const f1 = super.getValue();
+ const f2 = super.value;
+ }
+}
+
+var d = new MyDerived();
+var f3 = d.value;
+
+class A {
+ private _property: string;
+ get property() { return this._property; }
+ set property(value: string) { this._property = value }
+}
+
+class B extends A {
+ set property(value: string) {
+ super.property = value + " addition";
+ }
+}
+
+//// [superPropertyAccess_ES5.js]
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var MyBase = (function () {
+ function MyBase() {
+ }
+ MyBase.prototype.getValue = function () { return 1; };
+ Object.defineProperty(MyBase.prototype, "value", {
+ get: function () { return 1; },
+ enumerable: true,
+ configurable: true
+ });
+ return MyBase;
+}());
+var MyDerived = (function (_super) {
+ __extends(MyDerived, _super);
+ function MyDerived() {
+ _super.call(this);
+ var f1 = _super.prototype.getValue.call(this);
+ var f2 = _super.prototype.value;
+ }
+ return MyDerived;
+}(MyBase));
+var d = new MyDerived();
+var f3 = d.value;
+var A = (function () {
+ function A() {
+ }
+ Object.defineProperty(A.prototype, "property", {
+ get: function () { return this._property; },
+ set: function (value) { this._property = value; },
+ enumerable: true,
+ configurable: true
+ });
+ return A;
+}());
+var B = (function (_super) {
+ __extends(B, _super);
+ function B() {
+ _super.apply(this, arguments);
+ }
+ Object.defineProperty(B.prototype, "property", {
+ set: function (value) {
+ _super.prototype.property = value + " addition";
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return B;
+}(A));
diff --git a/tests/baselines/reference/superPropertyAccess_ES6.js b/tests/baselines/reference/superPropertyAccess_ES6.js
new file mode 100644
index 00000000000..1b23c6ca0d8
--- /dev/null
+++ b/tests/baselines/reference/superPropertyAccess_ES6.js
@@ -0,0 +1,54 @@
+//// [superPropertyAccess_ES6.ts]
+
+class MyBase {
+ getValue(): number { return 1; }
+ get value(): number { return 1; }
+}
+
+class MyDerived extends MyBase {
+ constructor() {
+ super();
+
+ const f1 = super.getValue();
+ const f2 = super.value;
+ }
+}
+
+var d = new MyDerived();
+var f3 = d.value;
+
+class A {
+ private _property: string;
+ get property() { return this._property; }
+ set property(value: string) { this._property = value }
+}
+
+class B extends A {
+ set property(value: string) {
+ super.property = value + " addition";
+ }
+}
+
+//// [superPropertyAccess_ES6.js]
+class MyBase {
+ getValue() { return 1; }
+ get value() { return 1; }
+}
+class MyDerived extends MyBase {
+ constructor() {
+ super();
+ const f1 = super.getValue();
+ const f2 = super.value;
+ }
+}
+var d = new MyDerived();
+var f3 = d.value;
+class A {
+ get property() { return this._property; }
+ set property(value) { this._property = value; }
+}
+class B extends A {
+ set property(value) {
+ super.property = value + " addition";
+ }
+}
diff --git a/tests/baselines/reference/superPropertyAccess_ES6.symbols b/tests/baselines/reference/superPropertyAccess_ES6.symbols
new file mode 100644
index 00000000000..ada6c5b8057
--- /dev/null
+++ b/tests/baselines/reference/superPropertyAccess_ES6.symbols
@@ -0,0 +1,80 @@
+=== tests/cases/compiler/superPropertyAccess_ES6.ts ===
+
+class MyBase {
+>MyBase : Symbol(MyBase, Decl(superPropertyAccess_ES6.ts, 0, 0))
+
+ getValue(): number { return 1; }
+>getValue : Symbol(getValue, Decl(superPropertyAccess_ES6.ts, 1, 14))
+
+ get value(): number { return 1; }
+>value : Symbol(value, Decl(superPropertyAccess_ES6.ts, 2, 34))
+}
+
+class MyDerived extends MyBase {
+>MyDerived : Symbol(MyDerived, Decl(superPropertyAccess_ES6.ts, 4, 1))
+>MyBase : Symbol(MyBase, Decl(superPropertyAccess_ES6.ts, 0, 0))
+
+ constructor() {
+ super();
+>super : Symbol(MyBase, Decl(superPropertyAccess_ES6.ts, 0, 0))
+
+ const f1 = super.getValue();
+>f1 : Symbol(f1, Decl(superPropertyAccess_ES6.ts, 10, 9))
+>super.getValue : Symbol(MyBase.getValue, Decl(superPropertyAccess_ES6.ts, 1, 14))
+>super : Symbol(MyBase, Decl(superPropertyAccess_ES6.ts, 0, 0))
+>getValue : Symbol(MyBase.getValue, Decl(superPropertyAccess_ES6.ts, 1, 14))
+
+ const f2 = super.value;
+>f2 : Symbol(f2, Decl(superPropertyAccess_ES6.ts, 11, 9))
+>super.value : Symbol(MyBase.value, Decl(superPropertyAccess_ES6.ts, 2, 34))
+>super : Symbol(MyBase, Decl(superPropertyAccess_ES6.ts, 0, 0))
+>value : Symbol(MyBase.value, Decl(superPropertyAccess_ES6.ts, 2, 34))
+ }
+}
+
+var d = new MyDerived();
+>d : Symbol(d, Decl(superPropertyAccess_ES6.ts, 15, 3))
+>MyDerived : Symbol(MyDerived, Decl(superPropertyAccess_ES6.ts, 4, 1))
+
+var f3 = d.value;
+>f3 : Symbol(f3, Decl(superPropertyAccess_ES6.ts, 16, 3))
+>d.value : Symbol(MyBase.value, Decl(superPropertyAccess_ES6.ts, 2, 34))
+>d : Symbol(d, Decl(superPropertyAccess_ES6.ts, 15, 3))
+>value : Symbol(MyBase.value, Decl(superPropertyAccess_ES6.ts, 2, 34))
+
+class A {
+>A : Symbol(A, Decl(superPropertyAccess_ES6.ts, 16, 17))
+
+ private _property: string;
+>_property : Symbol(_property, Decl(superPropertyAccess_ES6.ts, 18, 9))
+
+ get property() { return this._property; }
+>property : Symbol(property, Decl(superPropertyAccess_ES6.ts, 19, 30), Decl(superPropertyAccess_ES6.ts, 20, 45))
+>this._property : Symbol(_property, Decl(superPropertyAccess_ES6.ts, 18, 9))
+>this : Symbol(A, Decl(superPropertyAccess_ES6.ts, 16, 17))
+>_property : Symbol(_property, Decl(superPropertyAccess_ES6.ts, 18, 9))
+
+ set property(value: string) { this._property = value }
+>property : Symbol(property, Decl(superPropertyAccess_ES6.ts, 19, 30), Decl(superPropertyAccess_ES6.ts, 20, 45))
+>value : Symbol(value, Decl(superPropertyAccess_ES6.ts, 21, 17))
+>this._property : Symbol(_property, Decl(superPropertyAccess_ES6.ts, 18, 9))
+>this : Symbol(A, Decl(superPropertyAccess_ES6.ts, 16, 17))
+>_property : Symbol(_property, Decl(superPropertyAccess_ES6.ts, 18, 9))
+>value : Symbol(value, Decl(superPropertyAccess_ES6.ts, 21, 17))
+}
+
+class B extends A {
+>B : Symbol(B, Decl(superPropertyAccess_ES6.ts, 22, 1))
+>A : Symbol(A, Decl(superPropertyAccess_ES6.ts, 16, 17))
+
+ set property(value: string) {
+>property : Symbol(property, Decl(superPropertyAccess_ES6.ts, 24, 19))
+>value : Symbol(value, Decl(superPropertyAccess_ES6.ts, 25, 17))
+
+ super.property = value + " addition";
+>super.property : Symbol(A.property, Decl(superPropertyAccess_ES6.ts, 19, 30), Decl(superPropertyAccess_ES6.ts, 20, 45))
+>super : Symbol(A, Decl(superPropertyAccess_ES6.ts, 16, 17))
+>property : Symbol(A.property, Decl(superPropertyAccess_ES6.ts, 19, 30), Decl(superPropertyAccess_ES6.ts, 20, 45))
+>value : Symbol(value, Decl(superPropertyAccess_ES6.ts, 25, 17))
+ }
+}
diff --git a/tests/baselines/reference/superPropertyAccess_ES6.types b/tests/baselines/reference/superPropertyAccess_ES6.types
new file mode 100644
index 00000000000..b10b1944a44
--- /dev/null
+++ b/tests/baselines/reference/superPropertyAccess_ES6.types
@@ -0,0 +1,89 @@
+=== tests/cases/compiler/superPropertyAccess_ES6.ts ===
+
+class MyBase {
+>MyBase : MyBase
+
+ getValue(): number { return 1; }
+>getValue : () => number
+>1 : number
+
+ get value(): number { return 1; }
+>value : number
+>1 : number
+}
+
+class MyDerived extends MyBase {
+>MyDerived : MyDerived
+>MyBase : MyBase
+
+ constructor() {
+ super();
+>super() : void
+>super : typeof MyBase
+
+ const f1 = super.getValue();
+>f1 : number
+>super.getValue() : number
+>super.getValue : () => number
+>super : MyBase
+>getValue : () => number
+
+ const f2 = super.value;
+>f2 : number
+>super.value : number
+>super : MyBase
+>value : number
+ }
+}
+
+var d = new MyDerived();
+>d : MyDerived
+>new MyDerived() : MyDerived
+>MyDerived : typeof MyDerived
+
+var f3 = d.value;
+>f3 : number
+>d.value : number
+>d : MyDerived
+>value : number
+
+class A {
+>A : A
+
+ private _property: string;
+>_property : string
+
+ get property() { return this._property; }
+>property : string
+>this._property : string
+>this : this
+>_property : string
+
+ set property(value: string) { this._property = value }
+>property : string
+>value : string
+>this._property = value : string
+>this._property : string
+>this : this
+>_property : string
+>value : string
+}
+
+class B extends A {
+>B : B
+>A : A
+
+ set property(value: string) {
+>property : string
+>value : string
+
+ super.property = value + " addition";
+>super.property = value + " addition" : string
+>super.property : string
+>super : A
+>property : string
+>value + " addition" : string
+>value : string
+>" addition" : string
+ }
+}
diff --git a/tests/baselines/reference/typeAliasExport.js b/tests/baselines/reference/typeAliasExport.js
new file mode 100644
index 00000000000..fa864f571ea
--- /dev/null
+++ b/tests/baselines/reference/typeAliasExport.js
@@ -0,0 +1,8 @@
+//// [typeAliasExport.ts]
+declare module "a" {
+ export default 0
+ export var a;
+ export type a = typeof a;
+}
+
+//// [typeAliasExport.js]
diff --git a/tests/baselines/reference/typeAliasExport.symbols b/tests/baselines/reference/typeAliasExport.symbols
new file mode 100644
index 00000000000..1f580b03011
--- /dev/null
+++ b/tests/baselines/reference/typeAliasExport.symbols
@@ -0,0 +1,10 @@
+=== tests/cases/compiler/typeAliasExport.ts ===
+declare module "a" {
+ export default 0
+ export var a;
+>a : Symbol(a, Decl(typeAliasExport.ts, 2, 12), Decl(typeAliasExport.ts, 2, 15))
+
+ export type a = typeof a;
+>a : Symbol(a, Decl(typeAliasExport.ts, 2, 12), Decl(typeAliasExport.ts, 2, 15))
+>a : Symbol(a, Decl(typeAliasExport.ts, 2, 12), Decl(typeAliasExport.ts, 2, 15))
+}
diff --git a/tests/baselines/reference/typeAliasExport.types b/tests/baselines/reference/typeAliasExport.types
new file mode 100644
index 00000000000..afa26073061
--- /dev/null
+++ b/tests/baselines/reference/typeAliasExport.types
@@ -0,0 +1,10 @@
+=== tests/cases/compiler/typeAliasExport.ts ===
+declare module "a" {
+ export default 0
+ export var a;
+>a : any
+
+ export type a = typeof a;
+>a : any
+>a : any
+}
diff --git a/tests/cases/compiler/superPropertyAccess_ES5.ts b/tests/cases/compiler/superPropertyAccess_ES5.ts
new file mode 100644
index 00000000000..37897b9e549
--- /dev/null
+++ b/tests/cases/compiler/superPropertyAccess_ES5.ts
@@ -0,0 +1,30 @@
+// @target: ES5
+
+class MyBase {
+ getValue(): number { return 1; }
+ get value(): number { return 1; }
+}
+
+class MyDerived extends MyBase {
+ constructor() {
+ super();
+
+ const f1 = super.getValue();
+ const f2 = super.value;
+ }
+}
+
+var d = new MyDerived();
+var f3 = d.value;
+
+class A {
+ private _property: string;
+ get property() { return this._property; }
+ set property(value: string) { this._property = value }
+}
+
+class B extends A {
+ set property(value: string) {
+ super.property = value + " addition";
+ }
+}
\ No newline at end of file
diff --git a/tests/cases/compiler/superPropertyAccess_ES6.ts b/tests/cases/compiler/superPropertyAccess_ES6.ts
new file mode 100644
index 00000000000..ed082b19032
--- /dev/null
+++ b/tests/cases/compiler/superPropertyAccess_ES6.ts
@@ -0,0 +1,30 @@
+// @target: ES6
+
+class MyBase {
+ getValue(): number { return 1; }
+ get value(): number { return 1; }
+}
+
+class MyDerived extends MyBase {
+ constructor() {
+ super();
+
+ const f1 = super.getValue();
+ const f2 = super.value;
+ }
+}
+
+var d = new MyDerived();
+var f3 = d.value;
+
+class A {
+ private _property: string;
+ get property() { return this._property; }
+ set property(value: string) { this._property = value }
+}
+
+class B extends A {
+ set property(value: string) {
+ super.property = value + " addition";
+ }
+}
\ No newline at end of file
diff --git a/tests/cases/compiler/typeAliasExport.ts b/tests/cases/compiler/typeAliasExport.ts
new file mode 100644
index 00000000000..706b731f0ab
--- /dev/null
+++ b/tests/cases/compiler/typeAliasExport.ts
@@ -0,0 +1,5 @@
+declare module "a" {
+ export default 0
+ export var a;
+ export type a = typeof a;
+}
\ No newline at end of file
diff --git a/tests/cases/fourslash/thisPredicateFunctionCompletions.ts b/tests/cases/fourslash/thisPredicateFunctionCompletions.ts
new file mode 100644
index 00000000000..3c93a859bf3
--- /dev/null
+++ b/tests/cases/fourslash/thisPredicateFunctionCompletions.ts
@@ -0,0 +1,80 @@
+///
+
+//// class RoyalGuard {
+//// isLeader(): this is LeadGuard {
+//// return this instanceof LeadGuard;
+//// }
+//// isFollower(): this is FollowerGuard {
+//// return this instanceof FollowerGuard;
+//// }
+//// }
+////
+//// class LeadGuard extends RoyalGuard {
+//// lead(): void {};
+//// }
+////
+//// class FollowerGuard extends RoyalGuard {
+//// follow(): void {};
+//// }
+////
+//// let a: RoyalGuard = new FollowerGuard();
+//// if (a.is/*1*/Leader()) {
+//// a./*2*/;
+//// }
+//// else if (a.is/*3*/Follower()) {
+//// a./*4*/;
+//// }
+////
+//// interface GuardInterface {
+//// isLeader(): this is LeadGuard;
+//// isFollower(): this is FollowerGuard;
+//// }
+////
+//// let b: GuardInterface;
+//// if (b.is/*5*/Leader()) {
+//// b./*6*/;
+//// }
+//// else if (b.is/*7*/Follower()) {
+//// b./*8*/;
+//// }
+////
+//// if (((a.isLeader)())) {
+//// a./*9*/;
+//// }
+//// else if (((a).isFollower())) {
+//// a./*10*/;
+//// }
+////
+//// if (((a["isLeader"])())) {
+//// a./*11*/;
+//// }
+//// else if (((a)["isFollower"]())) {
+//// a./*12*/;
+//// }
+////
+//// let leader/*13*/Status = a.isLeader();
+//// function isLeaderGuard(g: RoyalGuard) {
+//// return g.isLeader();
+//// }
+//// let checked/*14*/LeaderStatus = isLeader/*15*/Guard(a);
+
+
+goTo.marker("2");
+verify.completionListContains("lead");
+goTo.marker("4");
+verify.completionListContains("follow");
+
+goTo.marker("6");
+verify.completionListContains("lead");
+goTo.marker("8");
+verify.completionListContains("follow");
+
+goTo.marker("9");
+verify.completionListContains("lead");
+goTo.marker("10");
+verify.completionListContains("follow");
+
+goTo.marker("11");
+verify.completionListContains("lead");
+goTo.marker("12");
+verify.completionListContains("follow");
\ No newline at end of file
diff --git a/tests/cases/fourslash/thisPredicateFunctionQuickInfo.ts b/tests/cases/fourslash/thisPredicateFunctionQuickInfo.ts
new file mode 100644
index 00000000000..3b7adc460c5
--- /dev/null
+++ b/tests/cases/fourslash/thisPredicateFunctionQuickInfo.ts
@@ -0,0 +1,77 @@
+///
+
+//// class RoyalGuard {
+//// isLeader(): this is LeadGuard {
+//// return this instanceof LeadGuard;
+//// }
+//// isFollower(): this is FollowerGuard {
+//// return this instanceof FollowerGuard;
+//// }
+//// }
+////
+//// class LeadGuard extends RoyalGuard {
+//// lead(): void {};
+//// }
+////
+//// class FollowerGuard extends RoyalGuard {
+//// follow(): void {};
+//// }
+////
+//// let a: RoyalGuard = new FollowerGuard();
+//// if (a.is/*1*/Leader()) {
+//// a./*2*/;
+//// }
+//// else if (a.is/*3*/Follower()) {
+//// a./*4*/;
+//// }
+////
+//// interface GuardInterface {
+//// isLeader(): this is LeadGuard;
+//// isFollower(): this is FollowerGuard;
+//// }
+////
+//// let b: GuardInterface;
+//// if (b.is/*5*/Leader()) {
+//// b./*6*/;
+//// }
+//// else if (b.is/*7*/Follower()) {
+//// b./*8*/;
+//// }
+////
+//// if (((a.isLeader)())) {
+//// a./*9*/;
+//// }
+//// else if (((a).isFollower())) {
+//// a./*10*/;
+//// }
+////
+//// if (((a["isLeader"])())) {
+//// a./*11*/;
+//// }
+//// else if (((a)["isFollower"]())) {
+//// a./*12*/;
+//// }
+////
+//// let leader/*13*/Status = a.isLeader();
+//// function isLeaderGuard(g: RoyalGuard) {
+//// return g.isLeader();
+//// }
+//// let checked/*14*/LeaderStatus = isLeader/*15*/Guard(a);
+
+
+goTo.marker("1");
+verify.quickInfoIs("(method) RoyalGuard.isLeader(): this is LeadGuard");
+goTo.marker("3");
+verify.quickInfoIs("(method) RoyalGuard.isFollower(): this is FollowerGuard");
+
+goTo.marker("5");
+verify.quickInfoIs("(method) GuardInterface.isLeader(): this is LeadGuard");
+goTo.marker("7");
+verify.quickInfoIs("(method) GuardInterface.isFollower(): this is FollowerGuard");
+
+goTo.marker("13");
+verify.quickInfoIs("let leaderStatus: boolean");
+goTo.marker("14");
+verify.quickInfoIs("let checkedLeaderStatus: boolean");
+goTo.marker("15");
+verify.quickInfoIs("function isLeaderGuard(g: RoyalGuard): boolean");
\ No newline at end of file
diff --git a/tests/cases/fourslash/thisPredicateMemberCompletions.ts b/tests/cases/fourslash/thisPredicateMemberCompletions.ts
new file mode 100644
index 00000000000..24ce742faac
--- /dev/null
+++ b/tests/cases/fourslash/thisPredicateMemberCompletions.ts
@@ -0,0 +1,95 @@
+///
+
+//// class FileSystemObject {
+//// get is/*1*/File(): this is Item {
+//// return this instanceof Item;
+//// }
+//// set is/*2*/File(param) {
+//// // noop
+//// }
+//// get is/*3*/Directory(): this is Directory {
+//// return this instanceof Directory;
+//// }
+//// is/*4*/Networked: this is (Networked & this);
+//// constructor(public path: string) {}
+//// }
+////
+//// class Item extends FileSystemObject {
+//// constructor(path: string, public content: string) { super(path); }
+//// }
+//// class Directory extends FileSystemObject {
+//// children: FileSystemObject[];
+//// }
+//// interface Networked {
+//// host: string;
+//// }
+////
+//// interface Sundries {
+//// broken: boolean;
+//// }
+////
+//// interface Supplies {
+//// spoiled: boolean;
+//// }
+////
+//// interface Crate {
+//// contents: T;
+//// is/*5*/Sundries: this is Crate;
+//// is/*6*/Supplies: this is Crate;
+//// is/*7*/PackedTight: this is (this & {extraContents: T});
+//// }
+////
+//// const obj: FileSystemObject = new Item("/foo", "");
+//// if (obj.is/*8*/File) {
+//// obj./*9*/;
+//// if (obj.is/*10*/Networked) {
+//// obj./*11*/;
+//// }
+//// }
+//// if (obj.is/*12*/Directory) {
+//// obj./*13*/;
+//// if (obj.is/*14*/Networked) {
+//// obj./*15*/;
+//// }
+//// }
+//// if (obj.is/*16*/Networked) {
+//// obj./*17*/;
+//// }
+////
+//// const crate: Crate;
+//// if (crate.is/*18*/PackedTight) {
+//// crate./*19*/;
+//// }
+//// if (crate.is/*20*/Sundries) {
+//// crate.contents./*21*/;
+//// if (crate.is/*22*/PackedTight) {
+//// crate./*23*/
+//// }
+//// }
+//// if (crate.is/*24*/Supplies) {
+//// crate.contents./*25*/;
+//// if (crate.is/*26*/PackedTight) {
+//// crate./*27*/
+//// }
+//// }
+
+goTo.marker("9");
+verify.completionListContains("content");
+goTo.marker("11");
+verify.completionListContains("host");
+goTo.marker("13");
+verify.completionListContains("children");
+goTo.marker("15");
+verify.completionListContains("host");
+goTo.marker("17");
+verify.completionListContains("host");
+goTo.marker("19");
+verify.completionListContains("extraContents");
+goTo.marker("21");
+verify.completionListContains("broken");
+goTo.marker("23");
+verify.completionListContains("extraContents");
+goTo.marker("25");
+verify.completionListContains("spoiled");
+goTo.marker("27");
+verify.completionListContains("extraContents");
\ No newline at end of file
diff --git a/tests/cases/fourslash/thisPredicateMemberQuickInfo.ts b/tests/cases/fourslash/thisPredicateMemberQuickInfo.ts
new file mode 100644
index 00000000000..20d519e0008
--- /dev/null
+++ b/tests/cases/fourslash/thisPredicateMemberQuickInfo.ts
@@ -0,0 +1,117 @@
+///
+
+//// class FileSystemObject {
+//// get is/*1*/File(): this is Item {
+//// return this instanceof Item;
+//// }
+//// set is/*2*/File(param) {
+//// // noop
+//// }
+//// get is/*3*/Directory(): this is Directory {
+//// return this instanceof Directory;
+//// }
+//// is/*4*/Networked: this is (Networked & this);
+//// constructor(public path: string) {}
+//// }
+////
+//// class Item extends FileSystemObject {
+//// constructor(path: string, public content: string) { super(path); }
+//// }
+//// class Directory extends FileSystemObject {
+//// children: FileSystemObject[];
+//// }
+//// interface Networked {
+//// host: string;
+//// }
+////
+//// interface Sundries {
+//// broken: boolean;
+//// }
+////
+//// interface Supplies {
+//// spoiled: boolean;
+//// }
+////
+//// interface Crate {
+//// contents: T;
+//// is/*5*/Sundries: this is Crate;
+//// is/*6*/Supplies: this is Crate;
+//// is/*7*/PackedTight: this is (this & {extraContents: T});
+//// }
+////
+//// const obj: FileSystemObject = new Item("/foo", "");
+//// if (obj.is/*8*/File) {
+//// obj./*9*/;
+//// if (obj.is/*10*/Networked) {
+//// obj./*11*/;
+//// }
+//// }
+//// if (obj.is/*12*/Directory) {
+//// obj./*13*/;
+//// if (obj.is/*14*/Networked) {
+//// obj./*15*/;
+//// }
+//// }
+//// if (obj.is/*16*/Networked) {
+//// obj./*17*/;
+//// }
+////
+//// const crate: Crate;
+//// if (crate.is/*18*/PackedTight) {
+//// crate./*19*/;
+//// }
+//// if (crate.is/*20*/Sundries) {
+//// crate.contents./*21*/;
+//// if (crate.is/*22*/PackedTight) {
+//// crate./*23*/
+//// }
+//// }
+//// if (crate.is/*24*/Supplies) {
+//// crate.contents./*25*/;
+//// if (crate.is/*26*/PackedTight) {
+//// crate./*27*/
+//// }
+//// }
+
+goTo.marker("1");
+verify.quickInfoIs("(property) FileSystemObject.isFile: this is Item");
+goTo.marker("2");
+verify.quickInfoIs("(property) FileSystemObject.isFile: this is Item");
+goTo.marker("3");
+verify.quickInfoIs("(property) FileSystemObject.isDirectory: this is Directory");
+goTo.marker("4");
+verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & this");
+goTo.marker("5");
+verify.quickInfoIs("(property) Crate.isSundries: this is Crate");
+goTo.marker("6");
+verify.quickInfoIs("(property) Crate.isSupplies: this is Crate");
+goTo.marker("7");
+verify.quickInfoIs(`(property) Crate.isPackedTight: this is this & {
+ extraContents: T;
+}`);
+goTo.marker("8");
+verify.quickInfoIs("(property) FileSystemObject.isFile: this is Item");
+goTo.marker("10");
+verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & Item");
+goTo.marker("12");
+verify.quickInfoIs("(property) FileSystemObject.isDirectory: this is Directory");
+goTo.marker("14");
+verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & Directory");
+goTo.marker("16");
+verify.quickInfoIs("(property) FileSystemObject.isNetworked: this is Networked & FileSystemObject");
+goTo.marker("18");
+verify.quickInfoIs(`(property) Crate.isPackedTight: this is Crate & {
+ extraContents: any;
+}`);
+goTo.marker("20");
+verify.quickInfoIs("(property) Crate.isSundries: this is Crate");
+goTo.marker("22");
+verify.quickInfoIs(`(property) Crate.isPackedTight: this is Crate & {
+ extraContents: Sundries;
+}`);
+goTo.marker("24");
+verify.quickInfoIs("(property) Crate.isSupplies: this is Crate");
+goTo.marker("26");
+verify.quickInfoIs(`(property) Crate.isPackedTight: this is Crate & {
+ extraContents: Supplies;
+}`);
\ No newline at end of file