mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
allow this in typeQuery (#43898)
* allow `this` in typeQuery * add tests * get this type as expression * handle nested nodes * update baselines
This commit is contained in:
+11
-6
@@ -13197,7 +13197,8 @@ namespace ts {
|
||||
// The expression is processed as an identifier expression (section 4.3)
|
||||
// or property access expression(section 4.10),
|
||||
// the widened type(section 3.9) of which becomes the result.
|
||||
links.resolvedType = getRegularTypeOfLiteralType(getWidenedType(checkExpression(node.exprName)));
|
||||
const type = isThisIdentifier(node.exprName) ? checkThisExpression(node.exprName) : checkExpression(node.exprName);
|
||||
links.resolvedType = getRegularTypeOfLiteralType(getWidenedType(type));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
@@ -21998,9 +21999,11 @@ namespace ts {
|
||||
&& (source as MetaProperty).name.escapedText === (target as MetaProperty).name.escapedText;
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.PrivateIdentifier:
|
||||
return target.kind === SyntaxKind.Identifier && getResolvedSymbol(source as Identifier) === getResolvedSymbol(target as Identifier) ||
|
||||
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) &&
|
||||
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as Identifier)) === getSymbolOfNode(target);
|
||||
return isThisInTypeQuery(source) ?
|
||||
target.kind === SyntaxKind.ThisKeyword :
|
||||
target.kind === SyntaxKind.Identifier && getResolvedSymbol(source as Identifier) === getResolvedSymbol(target as Identifier) ||
|
||||
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) &&
|
||||
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as Identifier)) === getSymbolOfNode(target);
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return target.kind === SyntaxKind.ThisKeyword;
|
||||
case SyntaxKind.SuperKeyword:
|
||||
@@ -24538,6 +24541,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkThisExpression(node: Node): Type {
|
||||
const isNodeInTypeQuery = isInTypeQuery(node);
|
||||
// Stop at the first arrow function so that we can
|
||||
// tell whether 'this' needs to be captured.
|
||||
let container = getThisContainer(node, /* includeArrowFunctions */ true);
|
||||
@@ -24581,7 +24585,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// When targeting es6, mark that we'll need to capture `this` in its lexically bound scope.
|
||||
if (capturedByArrowFunction && languageVersion < ScriptTarget.ES2015) {
|
||||
if (!isNodeInTypeQuery && capturedByArrowFunction && languageVersion < ScriptTarget.ES2015) {
|
||||
captureLexicalThis(node, container);
|
||||
}
|
||||
|
||||
@@ -27284,7 +27288,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkQualifiedName(node: QualifiedName, checkMode: CheckMode | undefined) {
|
||||
return checkPropertyAccessExpressionOrQualifiedName(node, node.left, checkNonNullExpression(node.left), node.right, checkMode);
|
||||
const leftType = isPartOfTypeQuery(node) && isThisIdentifier(node.left) ? checkNonNullType(checkThisExpression(node.left), node.left) : checkNonNullExpression(node.left);
|
||||
return checkPropertyAccessExpressionOrQualifiedName(node, node.left, leftType, node.right, checkMode);
|
||||
}
|
||||
|
||||
function isMethodAccessForCall(node: Node) {
|
||||
|
||||
@@ -4348,6 +4348,18 @@ namespace ts {
|
||||
return !!node && node.kind === SyntaxKind.Identifier && identifierIsThisKeyword(node as Identifier);
|
||||
}
|
||||
|
||||
export function isThisInTypeQuery(node: Node): boolean {
|
||||
if (!isThisIdentifier(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (isQualifiedName(node.parent) && node.parent.left === node) {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return node.parent.kind === SyntaxKind.TypeQuery;
|
||||
}
|
||||
|
||||
export function identifierIsThisKeyword(id: Identifier): boolean {
|
||||
return id.originalKeywordKind === SyntaxKind.ThisKeyword;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(4,9): error TS2304: Cannot find name 'z'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(5,15): error TS2304: Cannot find name 'z'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(6,14): error TS2339: Property 'z' does not exist on type 'C'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(7,15): error TS2304: Cannot find name 'this'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(7,20): error TS2339: Property 'z' does not exist on type 'C'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(9,9): error TS2304: Cannot find name 'z'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(14,9): error TS2304: Cannot find name 'z'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(15,15): error TS2304: Cannot find name 'z'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(16,14): error TS2339: Property 'z' does not exist on type 'D<T>'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(17,15): error TS2304: Cannot find name 'this'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(17,20): error TS2339: Property 'z' does not exist on type 'D<T>'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorLocals.ts(19,9): error TS2304: Cannot find name 'z'.
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin
|
||||
~
|
||||
!!! error TS2339: Property 'z' does not exist on type 'C'.
|
||||
d: typeof this.z; // error
|
||||
~~~~
|
||||
!!! error TS2304: Cannot find name 'this'.
|
||||
~
|
||||
!!! error TS2339: Property 'z' does not exist on type 'C'.
|
||||
constructor(x) {
|
||||
z = 1;
|
||||
~
|
||||
@@ -44,8 +44,8 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin
|
||||
~
|
||||
!!! error TS2339: Property 'z' does not exist on type 'D<T>'.
|
||||
d: typeof this.z; // error
|
||||
~~~~
|
||||
!!! error TS2304: Cannot find name 'this'.
|
||||
~
|
||||
!!! error TS2339: Property 'z' does not exist on type 'D<T>'.
|
||||
constructor(x: T) {
|
||||
z = 1;
|
||||
~
|
||||
|
||||
@@ -2,11 +2,10 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(5,15): error TS2304: Cannot find name 'x'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(10,9): error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'?
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(11,15): error TS2304: Cannot find name 'x'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(17,15): error TS2304: Cannot find name 'this'.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(23,9): error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'?
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts (6 errors) ====
|
||||
==== tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts (5 errors) ====
|
||||
// Initializer expressions for instance member variables are evaluated in the scope of the class constructor body but are not permitted to reference parameters or local variables of the constructor.
|
||||
|
||||
class C {
|
||||
@@ -31,9 +30,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin
|
||||
|
||||
class E {
|
||||
a = this.x; // ok
|
||||
b: typeof this.x; // error
|
||||
~~~~
|
||||
!!! error TS2304: Cannot find name 'this'.
|
||||
b: typeof this.x; // ok
|
||||
constructor(public x) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class D {
|
||||
|
||||
class E {
|
||||
a = this.x; // ok
|
||||
b: typeof this.x; // error
|
||||
b: typeof this.x; // ok
|
||||
constructor(public x) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,10 @@ class E {
|
||||
>this : Symbol(E, Decl(initializerReferencingConstructorParameters.ts, 12, 1))
|
||||
>x : Symbol(E.x, Decl(initializerReferencingConstructorParameters.ts, 17, 16))
|
||||
|
||||
b: typeof this.x; // error
|
||||
b: typeof this.x; // ok
|
||||
>b : Symbol(E.b, Decl(initializerReferencingConstructorParameters.ts, 15, 15))
|
||||
>this.x : Symbol(E.x, Decl(initializerReferencingConstructorParameters.ts, 17, 16))
|
||||
>x : Symbol(E.x, Decl(initializerReferencingConstructorParameters.ts, 17, 16))
|
||||
|
||||
constructor(public x) { }
|
||||
>x : Symbol(E.x, Decl(initializerReferencingConstructorParameters.ts, 17, 16))
|
||||
|
||||
@@ -40,7 +40,7 @@ class E {
|
||||
>this : this
|
||||
>x : any
|
||||
|
||||
b: typeof this.x; // error
|
||||
b: typeof this.x; // ok
|
||||
>b : any
|
||||
>this.x : any
|
||||
>this : any
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(24,19): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(32,19): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(46,23): error TS2331: 'this' cannot be referenced in a module or namespace body.
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(46,23): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(52,23): error TS2331: 'this' cannot be referenced in a module or namespace body.
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(52,23): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(57,19): error TS7041: The containing arrow function captures the global value of 'this'.
|
||||
tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(57,24): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts (8 errors) ====
|
||||
class Test {
|
||||
data = {};
|
||||
constructor() {
|
||||
var copy: typeof this.data = {};
|
||||
}
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
data = { foo: '' };
|
||||
['this'] = '';
|
||||
constructor() {
|
||||
var copy: typeof this.data = { foo: '' };
|
||||
var foo: typeof this.data.foo = '';
|
||||
|
||||
var self: typeof this = this;
|
||||
self.data;
|
||||
|
||||
var str: typeof this.this = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Test2() {
|
||||
let x: typeof this.no = 1;
|
||||
~~~~
|
||||
!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
}
|
||||
|
||||
function Test3(this: { no: number }) {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
function Test4(this: { no: number } | undefined) {
|
||||
let x: typeof this.no = 1;
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
|
||||
class Test5 {
|
||||
no = 1;
|
||||
|
||||
f = () => {
|
||||
// should not capture this.
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Test6 {
|
||||
export let f = () => {
|
||||
let x: typeof this.no = 1;
|
||||
~~~~
|
||||
!!! error TS2331: 'this' cannot be referenced in a module or namespace body.
|
||||
~~~~
|
||||
!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
}
|
||||
}
|
||||
|
||||
module Test7 {
|
||||
export let f = () => {
|
||||
let x: typeof this.no = 1;
|
||||
~~~~
|
||||
!!! error TS2331: 'this' cannot be referenced in a module or namespace body.
|
||||
~~~~
|
||||
!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
|
||||
}
|
||||
}
|
||||
|
||||
const Test8 = () => {
|
||||
let x: typeof this.no = 1;
|
||||
~~~~
|
||||
!!! error TS7041: The containing arrow function captures the global value of 'this'.
|
||||
~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
}
|
||||
|
||||
class Test9 {
|
||||
no = 0;
|
||||
this = 0;
|
||||
|
||||
f() {
|
||||
if (this instanceof Test9D1) {
|
||||
const d1: typeof this = this;
|
||||
d1.f1();
|
||||
}
|
||||
|
||||
if (this instanceof Test9D2) {
|
||||
const d2: typeof this = this;
|
||||
d2.f2();
|
||||
}
|
||||
}
|
||||
|
||||
g() {
|
||||
if (this.no === 1) {
|
||||
const no: typeof this.no = this.no;
|
||||
}
|
||||
|
||||
if (this.this === 1) {
|
||||
const no: typeof this.this = this.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test9D1 {
|
||||
f1() {}
|
||||
}
|
||||
|
||||
class Test9D2 {
|
||||
f2() {}
|
||||
}
|
||||
|
||||
class Test10 {
|
||||
a?: { b?: string }
|
||||
|
||||
foo() {
|
||||
let a: typeof this.a = undefined as any;
|
||||
if (this.a) {
|
||||
let a: typeof this.a = undefined as any; // should narrow to { b?: string }
|
||||
let b: typeof this.a.b = undefined as any;
|
||||
|
||||
if (this.a.b) {
|
||||
let b: typeof this.a.b = undefined as any; // should narrow to string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test11 {
|
||||
this?: { x?: string };
|
||||
|
||||
foo() {
|
||||
const o = this;
|
||||
let bar: typeof o.this = {};
|
||||
|
||||
if (o.this && o.this.x) {
|
||||
let y: string = o.this.x; // should narrow to string
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
//// [typeofThis.ts]
|
||||
class Test {
|
||||
data = {};
|
||||
constructor() {
|
||||
var copy: typeof this.data = {};
|
||||
}
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
data = { foo: '' };
|
||||
['this'] = '';
|
||||
constructor() {
|
||||
var copy: typeof this.data = { foo: '' };
|
||||
var foo: typeof this.data.foo = '';
|
||||
|
||||
var self: typeof this = this;
|
||||
self.data;
|
||||
|
||||
var str: typeof this.this = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Test2() {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
function Test3(this: { no: number }) {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
function Test4(this: { no: number } | undefined) {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
class Test5 {
|
||||
no = 1;
|
||||
|
||||
f = () => {
|
||||
// should not capture this.
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Test6 {
|
||||
export let f = () => {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
}
|
||||
|
||||
module Test7 {
|
||||
export let f = () => {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
}
|
||||
|
||||
const Test8 = () => {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
class Test9 {
|
||||
no = 0;
|
||||
this = 0;
|
||||
|
||||
f() {
|
||||
if (this instanceof Test9D1) {
|
||||
const d1: typeof this = this;
|
||||
d1.f1();
|
||||
}
|
||||
|
||||
if (this instanceof Test9D2) {
|
||||
const d2: typeof this = this;
|
||||
d2.f2();
|
||||
}
|
||||
}
|
||||
|
||||
g() {
|
||||
if (this.no === 1) {
|
||||
const no: typeof this.no = this.no;
|
||||
}
|
||||
|
||||
if (this.this === 1) {
|
||||
const no: typeof this.this = this.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test9D1 {
|
||||
f1() {}
|
||||
}
|
||||
|
||||
class Test9D2 {
|
||||
f2() {}
|
||||
}
|
||||
|
||||
class Test10 {
|
||||
a?: { b?: string }
|
||||
|
||||
foo() {
|
||||
let a: typeof this.a = undefined as any;
|
||||
if (this.a) {
|
||||
let a: typeof this.a = undefined as any; // should narrow to { b?: string }
|
||||
let b: typeof this.a.b = undefined as any;
|
||||
|
||||
if (this.a.b) {
|
||||
let b: typeof this.a.b = undefined as any; // should narrow to string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test11 {
|
||||
this?: { x?: string };
|
||||
|
||||
foo() {
|
||||
const o = this;
|
||||
let bar: typeof o.this = {};
|
||||
|
||||
if (o.this && o.this.x) {
|
||||
let y: string = o.this.x; // should narrow to string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// [typeofThis.js]
|
||||
"use strict";
|
||||
var Test = /** @class */ (function () {
|
||||
function Test() {
|
||||
this.data = {};
|
||||
var copy = {};
|
||||
}
|
||||
return Test;
|
||||
}());
|
||||
var Test1 = /** @class */ (function () {
|
||||
function Test1() {
|
||||
this.data = { foo: '' };
|
||||
this['this'] = '';
|
||||
var copy = { foo: '' };
|
||||
var foo = '';
|
||||
var self = this;
|
||||
self.data;
|
||||
var str = '';
|
||||
}
|
||||
return Test1;
|
||||
}());
|
||||
function Test2() {
|
||||
var x = 1;
|
||||
}
|
||||
function Test3() {
|
||||
var x = 1;
|
||||
}
|
||||
function Test4() {
|
||||
var x = 1;
|
||||
}
|
||||
var Test5 = /** @class */ (function () {
|
||||
function Test5() {
|
||||
this.no = 1;
|
||||
this.f = function () {
|
||||
// should not capture this.
|
||||
var x = 1;
|
||||
};
|
||||
}
|
||||
return Test5;
|
||||
}());
|
||||
var Test6;
|
||||
(function (Test6) {
|
||||
Test6.f = function () {
|
||||
var x = 1;
|
||||
};
|
||||
})(Test6 || (Test6 = {}));
|
||||
var Test7;
|
||||
(function (Test7) {
|
||||
Test7.f = function () {
|
||||
var x = 1;
|
||||
};
|
||||
})(Test7 || (Test7 = {}));
|
||||
var Test8 = function () {
|
||||
var x = 1;
|
||||
};
|
||||
var Test9 = /** @class */ (function () {
|
||||
function Test9() {
|
||||
this.no = 0;
|
||||
this["this"] = 0;
|
||||
}
|
||||
Test9.prototype.f = function () {
|
||||
if (this instanceof Test9D1) {
|
||||
var d1 = this;
|
||||
d1.f1();
|
||||
}
|
||||
if (this instanceof Test9D2) {
|
||||
var d2 = this;
|
||||
d2.f2();
|
||||
}
|
||||
};
|
||||
Test9.prototype.g = function () {
|
||||
if (this.no === 1) {
|
||||
var no = this.no;
|
||||
}
|
||||
if (this["this"] === 1) {
|
||||
var no = this["this"];
|
||||
}
|
||||
};
|
||||
return Test9;
|
||||
}());
|
||||
var Test9D1 = /** @class */ (function () {
|
||||
function Test9D1() {
|
||||
}
|
||||
Test9D1.prototype.f1 = function () { };
|
||||
return Test9D1;
|
||||
}());
|
||||
var Test9D2 = /** @class */ (function () {
|
||||
function Test9D2() {
|
||||
}
|
||||
Test9D2.prototype.f2 = function () { };
|
||||
return Test9D2;
|
||||
}());
|
||||
var Test10 = /** @class */ (function () {
|
||||
function Test10() {
|
||||
}
|
||||
Test10.prototype.foo = function () {
|
||||
var a = undefined;
|
||||
if (this.a) {
|
||||
var a_1 = undefined; // should narrow to { b?: string }
|
||||
var b = undefined;
|
||||
if (this.a.b) {
|
||||
var b_1 = undefined; // should narrow to string
|
||||
}
|
||||
}
|
||||
};
|
||||
return Test10;
|
||||
}());
|
||||
var Test11 = /** @class */ (function () {
|
||||
function Test11() {
|
||||
}
|
||||
Test11.prototype.foo = function () {
|
||||
var o = this;
|
||||
var bar = {};
|
||||
if (o["this"] && o["this"].x) {
|
||||
var y = o["this"].x; // should narrow to string
|
||||
}
|
||||
};
|
||||
return Test11;
|
||||
}());
|
||||
@@ -0,0 +1,314 @@
|
||||
=== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts ===
|
||||
class Test {
|
||||
>Test : Symbol(Test, Decl(typeofThis.ts, 0, 0))
|
||||
|
||||
data = {};
|
||||
>data : Symbol(Test.data, Decl(typeofThis.ts, 0, 12))
|
||||
|
||||
constructor() {
|
||||
var copy: typeof this.data = {};
|
||||
>copy : Symbol(copy, Decl(typeofThis.ts, 3, 11))
|
||||
>this.data : Symbol(Test.data, Decl(typeofThis.ts, 0, 12))
|
||||
>data : Symbol(Test.data, Decl(typeofThis.ts, 0, 12))
|
||||
}
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
>Test1 : Symbol(Test1, Decl(typeofThis.ts, 5, 1))
|
||||
|
||||
data = { foo: '' };
|
||||
>data : Symbol(Test1.data, Decl(typeofThis.ts, 7, 13))
|
||||
>foo : Symbol(foo, Decl(typeofThis.ts, 8, 12))
|
||||
|
||||
['this'] = '';
|
||||
>['this'] : Symbol(Test1['this'], Decl(typeofThis.ts, 8, 23))
|
||||
>'this' : Symbol(Test1['this'], Decl(typeofThis.ts, 8, 23))
|
||||
|
||||
constructor() {
|
||||
var copy: typeof this.data = { foo: '' };
|
||||
>copy : Symbol(copy, Decl(typeofThis.ts, 11, 11))
|
||||
>this.data : Symbol(Test1.data, Decl(typeofThis.ts, 7, 13))
|
||||
>data : Symbol(Test1.data, Decl(typeofThis.ts, 7, 13))
|
||||
>foo : Symbol(foo, Decl(typeofThis.ts, 11, 38))
|
||||
|
||||
var foo: typeof this.data.foo = '';
|
||||
>foo : Symbol(foo, Decl(typeofThis.ts, 12, 11))
|
||||
>this.data.foo : Symbol(foo, Decl(typeofThis.ts, 8, 12))
|
||||
>this.data : Symbol(Test1.data, Decl(typeofThis.ts, 7, 13))
|
||||
>data : Symbol(Test1.data, Decl(typeofThis.ts, 7, 13))
|
||||
>foo : Symbol(foo, Decl(typeofThis.ts, 8, 12))
|
||||
|
||||
var self: typeof this = this;
|
||||
>self : Symbol(self, Decl(typeofThis.ts, 14, 11))
|
||||
>this : Symbol(Test1, Decl(typeofThis.ts, 5, 1))
|
||||
|
||||
self.data;
|
||||
>self.data : Symbol(Test1.data, Decl(typeofThis.ts, 7, 13))
|
||||
>self : Symbol(self, Decl(typeofThis.ts, 14, 11))
|
||||
>data : Symbol(Test1.data, Decl(typeofThis.ts, 7, 13))
|
||||
|
||||
var str: typeof this.this = '';
|
||||
>str : Symbol(str, Decl(typeofThis.ts, 17, 11))
|
||||
>this.this : Symbol(Test1['this'], Decl(typeofThis.ts, 8, 23))
|
||||
>this : Symbol(Test1['this'], Decl(typeofThis.ts, 8, 23))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Test2() {
|
||||
>Test2 : Symbol(Test2, Decl(typeofThis.ts, 19, 1))
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 23, 7))
|
||||
}
|
||||
|
||||
function Test3(this: { no: number }) {
|
||||
>Test3 : Symbol(Test3, Decl(typeofThis.ts, 24, 1))
|
||||
>this : Symbol(this, Decl(typeofThis.ts, 26, 15))
|
||||
>no : Symbol(no, Decl(typeofThis.ts, 26, 22))
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 27, 7))
|
||||
>this.no : Symbol(no, Decl(typeofThis.ts, 26, 22))
|
||||
>this : Symbol(this, Decl(typeofThis.ts, 26, 15))
|
||||
>no : Symbol(no, Decl(typeofThis.ts, 26, 22))
|
||||
}
|
||||
|
||||
function Test4(this: { no: number } | undefined) {
|
||||
>Test4 : Symbol(Test4, Decl(typeofThis.ts, 28, 1))
|
||||
>this : Symbol(this, Decl(typeofThis.ts, 30, 15))
|
||||
>no : Symbol(no, Decl(typeofThis.ts, 30, 22))
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 31, 7))
|
||||
>this.no : Symbol(no, Decl(typeofThis.ts, 30, 22))
|
||||
>this : Symbol(this, Decl(typeofThis.ts, 30, 15))
|
||||
>no : Symbol(no, Decl(typeofThis.ts, 30, 22))
|
||||
}
|
||||
|
||||
class Test5 {
|
||||
>Test5 : Symbol(Test5, Decl(typeofThis.ts, 32, 1))
|
||||
|
||||
no = 1;
|
||||
>no : Symbol(Test5.no, Decl(typeofThis.ts, 34, 13))
|
||||
|
||||
f = () => {
|
||||
>f : Symbol(Test5.f, Decl(typeofThis.ts, 35, 11))
|
||||
|
||||
// should not capture this.
|
||||
let x: typeof this.no = 1;
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 39, 11))
|
||||
>this.no : Symbol(Test5.no, Decl(typeofThis.ts, 34, 13))
|
||||
>no : Symbol(Test5.no, Decl(typeofThis.ts, 34, 13))
|
||||
}
|
||||
}
|
||||
|
||||
namespace Test6 {
|
||||
>Test6 : Symbol(Test6, Decl(typeofThis.ts, 41, 1))
|
||||
|
||||
export let f = () => {
|
||||
>f : Symbol(f, Decl(typeofThis.ts, 44, 14))
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 45, 11))
|
||||
}
|
||||
}
|
||||
|
||||
module Test7 {
|
||||
>Test7 : Symbol(Test7, Decl(typeofThis.ts, 47, 1))
|
||||
|
||||
export let f = () => {
|
||||
>f : Symbol(f, Decl(typeofThis.ts, 50, 14))
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 51, 11))
|
||||
}
|
||||
}
|
||||
|
||||
const Test8 = () => {
|
||||
>Test8 : Symbol(Test8, Decl(typeofThis.ts, 55, 5))
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 56, 7))
|
||||
}
|
||||
|
||||
class Test9 {
|
||||
>Test9 : Symbol(Test9, Decl(typeofThis.ts, 57, 1))
|
||||
|
||||
no = 0;
|
||||
>no : Symbol(Test9.no, Decl(typeofThis.ts, 59, 13))
|
||||
|
||||
this = 0;
|
||||
>this : Symbol(Test9.this, Decl(typeofThis.ts, 60, 11))
|
||||
|
||||
f() {
|
||||
>f : Symbol(Test9.f, Decl(typeofThis.ts, 61, 13))
|
||||
|
||||
if (this instanceof Test9D1) {
|
||||
>this : Symbol(Test9, Decl(typeofThis.ts, 57, 1))
|
||||
>Test9D1 : Symbol(Test9D1, Decl(typeofThis.ts, 84, 1))
|
||||
|
||||
const d1: typeof this = this;
|
||||
>d1 : Symbol(d1, Decl(typeofThis.ts, 65, 17))
|
||||
|
||||
d1.f1();
|
||||
>d1.f1 : Symbol(Test9D1.f1, Decl(typeofThis.ts, 86, 15))
|
||||
>d1 : Symbol(d1, Decl(typeofThis.ts, 65, 17))
|
||||
>f1 : Symbol(Test9D1.f1, Decl(typeofThis.ts, 86, 15))
|
||||
}
|
||||
|
||||
if (this instanceof Test9D2) {
|
||||
>this : Symbol(Test9, Decl(typeofThis.ts, 57, 1))
|
||||
>Test9D2 : Symbol(Test9D2, Decl(typeofThis.ts, 88, 1))
|
||||
|
||||
const d2: typeof this = this;
|
||||
>d2 : Symbol(d2, Decl(typeofThis.ts, 70, 17))
|
||||
|
||||
d2.f2();
|
||||
>d2.f2 : Symbol(Test9D2.f2, Decl(typeofThis.ts, 90, 15))
|
||||
>d2 : Symbol(d2, Decl(typeofThis.ts, 70, 17))
|
||||
>f2 : Symbol(Test9D2.f2, Decl(typeofThis.ts, 90, 15))
|
||||
}
|
||||
}
|
||||
|
||||
g() {
|
||||
>g : Symbol(Test9.g, Decl(typeofThis.ts, 73, 5))
|
||||
|
||||
if (this.no === 1) {
|
||||
>this.no : Symbol(Test9.no, Decl(typeofThis.ts, 59, 13))
|
||||
>this : Symbol(Test9, Decl(typeofThis.ts, 57, 1))
|
||||
>no : Symbol(Test9.no, Decl(typeofThis.ts, 59, 13))
|
||||
|
||||
const no: typeof this.no = this.no;
|
||||
>no : Symbol(no, Decl(typeofThis.ts, 77, 17))
|
||||
>this.no : Symbol(Test9.no, Decl(typeofThis.ts, 59, 13))
|
||||
>no : Symbol(Test9.no, Decl(typeofThis.ts, 59, 13))
|
||||
>this.no : Symbol(Test9.no, Decl(typeofThis.ts, 59, 13))
|
||||
>this : Symbol(Test9, Decl(typeofThis.ts, 57, 1))
|
||||
>no : Symbol(Test9.no, Decl(typeofThis.ts, 59, 13))
|
||||
}
|
||||
|
||||
if (this.this === 1) {
|
||||
>this.this : Symbol(Test9.this, Decl(typeofThis.ts, 60, 11))
|
||||
>this : Symbol(Test9, Decl(typeofThis.ts, 57, 1))
|
||||
>this : Symbol(Test9.this, Decl(typeofThis.ts, 60, 11))
|
||||
|
||||
const no: typeof this.this = this.this;
|
||||
>no : Symbol(no, Decl(typeofThis.ts, 81, 17))
|
||||
>this.this : Symbol(Test9.this, Decl(typeofThis.ts, 60, 11))
|
||||
>this : Symbol(Test9.this, Decl(typeofThis.ts, 60, 11))
|
||||
>this.this : Symbol(Test9.this, Decl(typeofThis.ts, 60, 11))
|
||||
>this : Symbol(Test9, Decl(typeofThis.ts, 57, 1))
|
||||
>this : Symbol(Test9.this, Decl(typeofThis.ts, 60, 11))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test9D1 {
|
||||
>Test9D1 : Symbol(Test9D1, Decl(typeofThis.ts, 84, 1))
|
||||
|
||||
f1() {}
|
||||
>f1 : Symbol(Test9D1.f1, Decl(typeofThis.ts, 86, 15))
|
||||
}
|
||||
|
||||
class Test9D2 {
|
||||
>Test9D2 : Symbol(Test9D2, Decl(typeofThis.ts, 88, 1))
|
||||
|
||||
f2() {}
|
||||
>f2 : Symbol(Test9D2.f2, Decl(typeofThis.ts, 90, 15))
|
||||
}
|
||||
|
||||
class Test10 {
|
||||
>Test10 : Symbol(Test10, Decl(typeofThis.ts, 92, 1))
|
||||
|
||||
a?: { b?: string }
|
||||
>a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>b : Symbol(b, Decl(typeofThis.ts, 95, 9))
|
||||
|
||||
foo() {
|
||||
>foo : Symbol(Test10.foo, Decl(typeofThis.ts, 95, 22))
|
||||
|
||||
let a: typeof this.a = undefined as any;
|
||||
>a : Symbol(a, Decl(typeofThis.ts, 98, 11))
|
||||
>this.a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
if (this.a) {
|
||||
>this.a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>this : Symbol(Test10, Decl(typeofThis.ts, 92, 1))
|
||||
>a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
|
||||
let a: typeof this.a = undefined as any; // should narrow to { b?: string }
|
||||
>a : Symbol(a, Decl(typeofThis.ts, 100, 15))
|
||||
>this.a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
let b: typeof this.a.b = undefined as any;
|
||||
>b : Symbol(b, Decl(typeofThis.ts, 101, 15))
|
||||
>this.a.b : Symbol(b, Decl(typeofThis.ts, 95, 9))
|
||||
>this.a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>b : Symbol(b, Decl(typeofThis.ts, 95, 9))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
if (this.a.b) {
|
||||
>this.a.b : Symbol(b, Decl(typeofThis.ts, 95, 9))
|
||||
>this.a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>this : Symbol(Test10, Decl(typeofThis.ts, 92, 1))
|
||||
>a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>b : Symbol(b, Decl(typeofThis.ts, 95, 9))
|
||||
|
||||
let b: typeof this.a.b = undefined as any; // should narrow to string
|
||||
>b : Symbol(b, Decl(typeofThis.ts, 104, 19))
|
||||
>this.a.b : Symbol(b, Decl(typeofThis.ts, 95, 9))
|
||||
>this.a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>a : Symbol(Test10.a, Decl(typeofThis.ts, 94, 14))
|
||||
>b : Symbol(b, Decl(typeofThis.ts, 95, 9))
|
||||
>undefined : Symbol(undefined)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test11 {
|
||||
>Test11 : Symbol(Test11, Decl(typeofThis.ts, 108, 1))
|
||||
|
||||
this?: { x?: string };
|
||||
>this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 111, 12))
|
||||
|
||||
foo() {
|
||||
>foo : Symbol(Test11.foo, Decl(typeofThis.ts, 111, 26))
|
||||
|
||||
const o = this;
|
||||
>o : Symbol(o, Decl(typeofThis.ts, 114, 13))
|
||||
>this : Symbol(Test11, Decl(typeofThis.ts, 108, 1))
|
||||
|
||||
let bar: typeof o.this = {};
|
||||
>bar : Symbol(bar, Decl(typeofThis.ts, 115, 11))
|
||||
>o.this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>o : Symbol(o, Decl(typeofThis.ts, 114, 13))
|
||||
>this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
|
||||
if (o.this && o.this.x) {
|
||||
>o.this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>o : Symbol(o, Decl(typeofThis.ts, 114, 13))
|
||||
>this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>o.this.x : Symbol(x, Decl(typeofThis.ts, 111, 12))
|
||||
>o.this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>o : Symbol(o, Decl(typeofThis.ts, 114, 13))
|
||||
>this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 111, 12))
|
||||
|
||||
let y: string = o.this.x; // should narrow to string
|
||||
>y : Symbol(y, Decl(typeofThis.ts, 118, 15))
|
||||
>o.this.x : Symbol(x, Decl(typeofThis.ts, 111, 12))
|
||||
>o.this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>o : Symbol(o, Decl(typeofThis.ts, 114, 13))
|
||||
>this : Symbol(Test11.this, Decl(typeofThis.ts, 110, 14))
|
||||
>x : Symbol(x, Decl(typeofThis.ts, 111, 12))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
=== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts ===
|
||||
class Test {
|
||||
>Test : Test
|
||||
|
||||
data = {};
|
||||
>data : {}
|
||||
>{} : {}
|
||||
|
||||
constructor() {
|
||||
var copy: typeof this.data = {};
|
||||
>copy : {}
|
||||
>this.data : {}
|
||||
>this : any
|
||||
>data : {}
|
||||
>{} : {}
|
||||
}
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
>Test1 : Test1
|
||||
|
||||
data = { foo: '' };
|
||||
>data : { foo: string; }
|
||||
>{ foo: '' } : { foo: string; }
|
||||
>foo : string
|
||||
>'' : ""
|
||||
|
||||
['this'] = '';
|
||||
>['this'] : string
|
||||
>'this' : "this"
|
||||
>'' : ""
|
||||
|
||||
constructor() {
|
||||
var copy: typeof this.data = { foo: '' };
|
||||
>copy : { foo: string; }
|
||||
>this.data : { foo: string; }
|
||||
>this : any
|
||||
>data : { foo: string; }
|
||||
>{ foo: '' } : { foo: string; }
|
||||
>foo : string
|
||||
>'' : ""
|
||||
|
||||
var foo: typeof this.data.foo = '';
|
||||
>foo : string
|
||||
>this.data.foo : string
|
||||
>this.data : { foo: string; }
|
||||
>this : any
|
||||
>data : { foo: string; }
|
||||
>foo : string
|
||||
>'' : ""
|
||||
|
||||
var self: typeof this = this;
|
||||
>self : this
|
||||
>this : any
|
||||
>this : this
|
||||
|
||||
self.data;
|
||||
>self.data : { foo: string; }
|
||||
>self : this
|
||||
>data : { foo: string; }
|
||||
|
||||
var str: typeof this.this = '';
|
||||
>str : string
|
||||
>this.this : string
|
||||
>this : any
|
||||
>this : string
|
||||
>'' : ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Test2() {
|
||||
>Test2 : () => void
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : any
|
||||
>this.no : any
|
||||
>this : any
|
||||
>no : any
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
function Test3(this: { no: number }) {
|
||||
>Test3 : (this: { no: number;}) => void
|
||||
>this : { no: number; }
|
||||
>no : number
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : number
|
||||
>this.no : number
|
||||
>this : { no: number; }
|
||||
>no : number
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
function Test4(this: { no: number } | undefined) {
|
||||
>Test4 : (this: { no: number;} | undefined) => void
|
||||
>this : { no: number; } | undefined
|
||||
>no : number
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : number
|
||||
>this.no : number
|
||||
>this : { no: number; } | undefined
|
||||
>no : number
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
class Test5 {
|
||||
>Test5 : Test5
|
||||
|
||||
no = 1;
|
||||
>no : number
|
||||
>1 : 1
|
||||
|
||||
f = () => {
|
||||
>f : () => void
|
||||
>() => { // should not capture this. let x: typeof this.no = 1; } : () => void
|
||||
|
||||
// should not capture this.
|
||||
let x: typeof this.no = 1;
|
||||
>x : number
|
||||
>this.no : number
|
||||
>this : any
|
||||
>no : number
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
namespace Test6 {
|
||||
>Test6 : typeof Test6
|
||||
|
||||
export let f = () => {
|
||||
>f : () => void
|
||||
>() => { let x: typeof this.no = 1; } : () => void
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : any
|
||||
>this.no : any
|
||||
>this : any
|
||||
>no : any
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
module Test7 {
|
||||
>Test7 : typeof Test7
|
||||
|
||||
export let f = () => {
|
||||
>f : () => void
|
||||
>() => { let x: typeof this.no = 1; } : () => void
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : any
|
||||
>this.no : any
|
||||
>this : any
|
||||
>no : any
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
const Test8 = () => {
|
||||
>Test8 : () => void
|
||||
>() => { let x: typeof this.no = 1;} : () => void
|
||||
|
||||
let x: typeof this.no = 1;
|
||||
>x : any
|
||||
>this.no : any
|
||||
>this : any
|
||||
>no : any
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
class Test9 {
|
||||
>Test9 : Test9
|
||||
|
||||
no = 0;
|
||||
>no : number
|
||||
>0 : 0
|
||||
|
||||
this = 0;
|
||||
>this : number
|
||||
>0 : 0
|
||||
|
||||
f() {
|
||||
>f : () => void
|
||||
|
||||
if (this instanceof Test9D1) {
|
||||
>this instanceof Test9D1 : boolean
|
||||
>this : this
|
||||
>Test9D1 : typeof Test9D1
|
||||
|
||||
const d1: typeof this = this;
|
||||
>d1 : this & Test9D1
|
||||
>this : any
|
||||
>this : this & Test9D1
|
||||
|
||||
d1.f1();
|
||||
>d1.f1() : void
|
||||
>d1.f1 : () => void
|
||||
>d1 : this & Test9D1
|
||||
>f1 : () => void
|
||||
}
|
||||
|
||||
if (this instanceof Test9D2) {
|
||||
>this instanceof Test9D2 : boolean
|
||||
>this : this
|
||||
>Test9D2 : typeof Test9D2
|
||||
|
||||
const d2: typeof this = this;
|
||||
>d2 : this & Test9D2
|
||||
>this : any
|
||||
>this : this & Test9D2
|
||||
|
||||
d2.f2();
|
||||
>d2.f2() : void
|
||||
>d2.f2 : () => void
|
||||
>d2 : this & Test9D2
|
||||
>f2 : () => void
|
||||
}
|
||||
}
|
||||
|
||||
g() {
|
||||
>g : () => void
|
||||
|
||||
if (this.no === 1) {
|
||||
>this.no === 1 : boolean
|
||||
>this.no : number
|
||||
>this : this
|
||||
>no : number
|
||||
>1 : 1
|
||||
|
||||
const no: typeof this.no = this.no;
|
||||
>no : 1
|
||||
>this.no : 1
|
||||
>this : any
|
||||
>no : 1
|
||||
>this.no : 1
|
||||
>this : this
|
||||
>no : 1
|
||||
}
|
||||
|
||||
if (this.this === 1) {
|
||||
>this.this === 1 : boolean
|
||||
>this.this : number
|
||||
>this : this
|
||||
>this : number
|
||||
>1 : 1
|
||||
|
||||
const no: typeof this.this = this.this;
|
||||
>no : 1
|
||||
>this.this : 1
|
||||
>this : any
|
||||
>this : 1
|
||||
>this.this : 1
|
||||
>this : this
|
||||
>this : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test9D1 {
|
||||
>Test9D1 : Test9D1
|
||||
|
||||
f1() {}
|
||||
>f1 : () => void
|
||||
}
|
||||
|
||||
class Test9D2 {
|
||||
>Test9D2 : Test9D2
|
||||
|
||||
f2() {}
|
||||
>f2 : () => void
|
||||
}
|
||||
|
||||
class Test10 {
|
||||
>Test10 : Test10
|
||||
|
||||
a?: { b?: string }
|
||||
>a : { b?: string; } | undefined
|
||||
>b : string | undefined
|
||||
|
||||
foo() {
|
||||
>foo : () => void
|
||||
|
||||
let a: typeof this.a = undefined as any;
|
||||
>a : { b?: string; } | undefined
|
||||
>this.a : { b?: string; } | undefined
|
||||
>this : any
|
||||
>a : { b?: string; } | undefined
|
||||
>undefined as any : any
|
||||
>undefined : undefined
|
||||
|
||||
if (this.a) {
|
||||
>this.a : { b?: string; } | undefined
|
||||
>this : this
|
||||
>a : { b?: string; } | undefined
|
||||
|
||||
let a: typeof this.a = undefined as any; // should narrow to { b?: string }
|
||||
>a : { b?: string; }
|
||||
>this.a : { b?: string; }
|
||||
>this : any
|
||||
>a : { b?: string; }
|
||||
>undefined as any : any
|
||||
>undefined : undefined
|
||||
|
||||
let b: typeof this.a.b = undefined as any;
|
||||
>b : string | undefined
|
||||
>this.a.b : string | undefined
|
||||
>this.a : { b?: string; }
|
||||
>this : any
|
||||
>a : { b?: string; }
|
||||
>b : string | undefined
|
||||
>undefined as any : any
|
||||
>undefined : undefined
|
||||
|
||||
if (this.a.b) {
|
||||
>this.a.b : string | undefined
|
||||
>this.a : { b?: string; }
|
||||
>this : this
|
||||
>a : { b?: string; }
|
||||
>b : string | undefined
|
||||
|
||||
let b: typeof this.a.b = undefined as any; // should narrow to string
|
||||
>b : string
|
||||
>this.a.b : string
|
||||
>this.a : { b?: string; }
|
||||
>this : any
|
||||
>a : { b?: string; }
|
||||
>b : string
|
||||
>undefined as any : any
|
||||
>undefined : undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test11 {
|
||||
>Test11 : Test11
|
||||
|
||||
this?: { x?: string };
|
||||
>this : { x?: string; } | undefined
|
||||
>x : string | undefined
|
||||
|
||||
foo() {
|
||||
>foo : () => void
|
||||
|
||||
const o = this;
|
||||
>o : this
|
||||
>this : this
|
||||
|
||||
let bar: typeof o.this = {};
|
||||
>bar : { x?: string; } | undefined
|
||||
>o.this : { x?: string; } | undefined
|
||||
>o : this
|
||||
>this : { x?: string; } | undefined
|
||||
>{} : {}
|
||||
|
||||
if (o.this && o.this.x) {
|
||||
>o.this && o.this.x : string | undefined
|
||||
>o.this : { x?: string; } | undefined
|
||||
>o : this
|
||||
>this : { x?: string; } | undefined
|
||||
>o.this.x : string | undefined
|
||||
>o.this : { x?: string; }
|
||||
>o : this
|
||||
>this : { x?: string; }
|
||||
>x : string | undefined
|
||||
|
||||
let y: string = o.this.x; // should narrow to string
|
||||
>y : string
|
||||
>o.this.x : string
|
||||
>o.this : { x?: string; }
|
||||
>o : this
|
||||
>this : { x?: string; }
|
||||
>x : string
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
//// [typeofThisWithImplicitThis.ts]
|
||||
function Test1() {
|
||||
let x: typeof this.no = 1
|
||||
}
|
||||
|
||||
|
||||
//// [typeofThisWithImplicitThis.js]
|
||||
function Test1() {
|
||||
var x = 1;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThisWithImplicitThis.ts ===
|
||||
function Test1() {
|
||||
>Test1 : Symbol(Test1, Decl(typeofThisWithImplicitThis.ts, 0, 0))
|
||||
|
||||
let x: typeof this.no = 1
|
||||
>x : Symbol(x, Decl(typeofThisWithImplicitThis.ts, 1, 7))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThisWithImplicitThis.ts ===
|
||||
function Test1() {
|
||||
>Test1 : () => void
|
||||
|
||||
let x: typeof this.no = 1
|
||||
>x : any
|
||||
>this.no : any
|
||||
>this : any
|
||||
>no : any
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ class D {
|
||||
|
||||
class E {
|
||||
a = this.x; // ok
|
||||
b: typeof this.x; // error
|
||||
b: typeof this.x; // ok
|
||||
constructor(public x) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
// @noImplicitThis: true
|
||||
// @strict: true
|
||||
|
||||
class Test {
|
||||
data = {};
|
||||
constructor() {
|
||||
var copy: typeof this.data = {};
|
||||
}
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
data = { foo: '' };
|
||||
['this'] = '';
|
||||
constructor() {
|
||||
var copy: typeof this.data = { foo: '' };
|
||||
var foo: typeof this.data.foo = '';
|
||||
|
||||
var self: typeof this = this;
|
||||
self.data;
|
||||
|
||||
var str: typeof this.this = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Test2() {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
function Test3(this: { no: number }) {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
function Test4(this: { no: number } | undefined) {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
class Test5 {
|
||||
no = 1;
|
||||
|
||||
f = () => {
|
||||
// should not capture this.
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Test6 {
|
||||
export let f = () => {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
}
|
||||
|
||||
module Test7 {
|
||||
export let f = () => {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
}
|
||||
|
||||
const Test8 = () => {
|
||||
let x: typeof this.no = 1;
|
||||
}
|
||||
|
||||
class Test9 {
|
||||
no = 0;
|
||||
this = 0;
|
||||
|
||||
f() {
|
||||
if (this instanceof Test9D1) {
|
||||
const d1: typeof this = this;
|
||||
d1.f1();
|
||||
}
|
||||
|
||||
if (this instanceof Test9D2) {
|
||||
const d2: typeof this = this;
|
||||
d2.f2();
|
||||
}
|
||||
}
|
||||
|
||||
g() {
|
||||
if (this.no === 1) {
|
||||
const no: typeof this.no = this.no;
|
||||
}
|
||||
|
||||
if (this.this === 1) {
|
||||
const no: typeof this.this = this.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test9D1 {
|
||||
f1() {}
|
||||
}
|
||||
|
||||
class Test9D2 {
|
||||
f2() {}
|
||||
}
|
||||
|
||||
class Test10 {
|
||||
a?: { b?: string }
|
||||
|
||||
foo() {
|
||||
let a: typeof this.a = undefined as any;
|
||||
if (this.a) {
|
||||
let a: typeof this.a = undefined as any; // should narrow to { b?: string }
|
||||
let b: typeof this.a.b = undefined as any;
|
||||
|
||||
if (this.a.b) {
|
||||
let b: typeof this.a.b = undefined as any; // should narrow to string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test11 {
|
||||
this?: { x?: string };
|
||||
|
||||
foo() {
|
||||
const o = this;
|
||||
let bar: typeof o.this = {};
|
||||
|
||||
if (o.this && o.this.x) {
|
||||
let y: string = o.this.x; // should narrow to string
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// @noImplicitThis: false
|
||||
|
||||
function Test1() {
|
||||
let x: typeof this.no = 1
|
||||
}
|
||||
Reference in New Issue
Block a user