mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-11 01:34:55 -06:00
Add tests and baselines for this-function types.
This commit is contained in:
parent
5fe8478159
commit
04e7d81105
@ -0,0 +1,48 @@
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(20,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'void' is not assignable to type 'C'.
|
||||
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(27,9): error TS2345: Argument of type 'void' is not assignable to parameter of type 'I'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (2 errors) ====
|
||||
interface I {
|
||||
explicitThis(this: this, m: number): number;
|
||||
}
|
||||
interface Unused {
|
||||
implicitNoThis(m: number): number;
|
||||
}
|
||||
class C implements I {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return m + 1;
|
||||
}
|
||||
}
|
||||
let c = new C();
|
||||
c.explicitVoid = c.explicitThis; // error, 'void' is missing everything
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'C'.
|
||||
let o = {
|
||||
explicitThis: function (m) { return m },
|
||||
implicitThis(m: number): number { return m }
|
||||
};
|
||||
let i: I = o;
|
||||
let x = i.explicitThis;
|
||||
let n = x(12); // callee:void doesn't match this:I
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type 'void' is not assignable to parameter of type 'I'.
|
||||
let u: Unused;
|
||||
let y = u.implicitNoThis;
|
||||
n = y(12); // ok, callee:void matches this:any
|
||||
c.explicitVoid = c.implicitThis // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.implicitThis; // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.explicitThis; // ok, implicitThis(this:any) is assignable to explicitThis(this: this)
|
||||
o.implicitThis = i.explicitThis;
|
||||
|
||||
68
tests/baselines/reference/looseThisTypeInFunctions.js
Normal file
68
tests/baselines/reference/looseThisTypeInFunctions.js
Normal file
@ -0,0 +1,68 @@
|
||||
//// [looseThisTypeInFunctions.ts]
|
||||
interface I {
|
||||
explicitThis(this: this, m: number): number;
|
||||
}
|
||||
interface Unused {
|
||||
implicitNoThis(m: number): number;
|
||||
}
|
||||
class C implements I {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return m + 1;
|
||||
}
|
||||
}
|
||||
let c = new C();
|
||||
c.explicitVoid = c.explicitThis; // error, 'void' is missing everything
|
||||
let o = {
|
||||
explicitThis: function (m) { return m },
|
||||
implicitThis(m: number): number { return m }
|
||||
};
|
||||
let i: I = o;
|
||||
let x = i.explicitThis;
|
||||
let n = x(12); // callee:void doesn't match this:I
|
||||
let u: Unused;
|
||||
let y = u.implicitNoThis;
|
||||
n = y(12); // ok, callee:void matches this:any
|
||||
c.explicitVoid = c.implicitThis // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.implicitThis; // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.explicitThis; // ok, implicitThis(this:any) is assignable to explicitThis(this: this)
|
||||
o.implicitThis = i.explicitThis;
|
||||
|
||||
|
||||
//// [looseThisTypeInFunctions.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.explicitThis = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.implicitThis = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.explicitVoid = function (m) {
|
||||
return m + 1;
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
var c = new C();
|
||||
c.explicitVoid = c.explicitThis; // error, 'void' is missing everything
|
||||
var o = {
|
||||
explicitThis: function (m) { return m; },
|
||||
implicitThis: function (m) { return m; }
|
||||
};
|
||||
var i = o;
|
||||
var x = i.explicitThis;
|
||||
var n = x(12); // callee:void doesn't match this:I
|
||||
var u;
|
||||
var y = u.implicitNoThis;
|
||||
n = y(12); // ok, callee:void matches this:any
|
||||
c.explicitVoid = c.implicitThis; // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.implicitThis; // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.explicitThis; // ok, implicitThis(this:any) is assignable to explicitThis(this: this)
|
||||
o.implicitThis = i.explicitThis;
|
||||
407
tests/baselines/reference/thisTypeInFunctions.js
Normal file
407
tests/baselines/reference/thisTypeInFunctions.js
Normal file
@ -0,0 +1,407 @@
|
||||
//// [thisTypeInFunctions.ts]
|
||||
// body checking
|
||||
class C {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitC(this: C, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitProperty(this: {n: number}, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return m + 1;
|
||||
}
|
||||
}
|
||||
class D extends C { }
|
||||
class B {
|
||||
n: number;
|
||||
}
|
||||
interface I {
|
||||
a: number;
|
||||
explicitVoid1(this: void): number;
|
||||
explicitVoid2(this: void): number;
|
||||
explicitStructural(this: {a: number}): number;
|
||||
explicitInterface(this: I): number;
|
||||
explicitThis(this: this): number;
|
||||
implicitMethod(): number;
|
||||
implicitFunction: () => number;
|
||||
}
|
||||
function explicitStructural(this: { y: number }, x: number): number {
|
||||
return x + this.y;
|
||||
}
|
||||
function justThis(this: { y: number }): number {
|
||||
return this.y;
|
||||
}
|
||||
function implicitThis(n: number): number {
|
||||
return 12;
|
||||
}
|
||||
let impl: I = {
|
||||
a: 12,
|
||||
explicitVoid2: () => this.a, // ok, this: any because it refers to some outer object (window?)
|
||||
explicitVoid1() { return 12; },
|
||||
explicitStructural() {
|
||||
return this.a;
|
||||
},
|
||||
explicitInterface() {
|
||||
return this.a;
|
||||
},
|
||||
explicitThis() {
|
||||
return this.a;
|
||||
},
|
||||
implicitMethod() {
|
||||
return this.a;
|
||||
},
|
||||
implicitFunction: () => this.a, // ok, this: any because it refers to some outer object (window?)
|
||||
}
|
||||
impl.explicitVoid1 = function () { return 12; };
|
||||
impl.explicitVoid2 = () => 12;
|
||||
impl.explicitStructural = function() { return this.a; };
|
||||
impl.explicitInterface = function() { return this.a; };
|
||||
impl.explicitStructural = () => 12;
|
||||
impl.explicitInterface = () => 12;
|
||||
impl.explicitThis = function () { return this.a; };
|
||||
impl.implicitMethod = function () { return this.a; };
|
||||
impl.implicitMethod = () => 12;
|
||||
impl.implicitFunction = () => this.a; // ok, this: any because it refers to some outer object (window?)
|
||||
// parameter checking
|
||||
let ok: {y: number, f: (this: { y: number }, x: number) => number} = { y: 12, f: explicitStructural };
|
||||
let implicitAnyOk: {notSpecified: number, f: (x: number) => number} = { notSpecified: 12, f: implicitThis };
|
||||
ok.f(13);
|
||||
implicitThis(12);
|
||||
implicitAnyOk.f(12);
|
||||
|
||||
let c = new C();
|
||||
let d = new D();
|
||||
let ripped = c.explicitC;
|
||||
c.explicitC(12);
|
||||
c.explicitProperty(12);
|
||||
c.explicitThis(12);
|
||||
c.implicitThis(12);
|
||||
d.explicitC(12);
|
||||
d.explicitProperty(12);
|
||||
d.explicitThis(12);
|
||||
d.implicitThis(12);
|
||||
let reconstructed: {
|
||||
n: number,
|
||||
explicitThis(this: C, m: number): number, // note: this: this is not allowed in an object literal type.
|
||||
implicitThis(m: number): number,
|
||||
explicitC(this: C, m: number): number,
|
||||
explicitProperty: (this: {n : number}, m: number) => number,
|
||||
explicitVoid(this: void, m: number): number,
|
||||
} = {
|
||||
n: 12,
|
||||
explicitThis: c.explicitThis,
|
||||
implicitThis: c.implicitThis,
|
||||
explicitC: c.explicitC,
|
||||
explicitProperty: c.explicitProperty,
|
||||
explicitVoid: c.explicitVoid
|
||||
};
|
||||
reconstructed.explicitProperty(11);
|
||||
reconstructed.implicitThis(11);
|
||||
|
||||
// assignment checking
|
||||
let unboundToSpecified: (this: { y: number }, x: number) => number = x => x + this.y; // ok, this:any
|
||||
let specifiedToSpecified: (this: {y: number}, x: number) => number = explicitStructural;
|
||||
let anyToSpecified: (this: { y: number }, x: number) => number = function(x: number): number { return x + 12; };
|
||||
|
||||
let unspecifiedLambda: (x: number) => number = x => x + 12;
|
||||
let specifiedLambda: (this: void, x: number) => number = x => x + 12;
|
||||
let unspecifiedLambdaToSpecified: (this: {y: number}, x: number) => number = unspecifiedLambda;
|
||||
let specifiedLambdaToSpecified: (this: {y: number}, x: number) => number = specifiedLambda;
|
||||
|
||||
|
||||
let explicitCFunction: (this: C, m: number) => number;
|
||||
let explicitPropertyFunction: (this: {n: number}, m: number) => number;
|
||||
c.explicitC = explicitCFunction;
|
||||
c.explicitC = function(this: C, m: number) { return this.n + m };
|
||||
c.explicitProperty = explicitPropertyFunction;
|
||||
c.explicitProperty = function(this: {n: number}, m: number) { return this.n + m };
|
||||
c.explicitProperty = reconstructed.explicitProperty;
|
||||
|
||||
// lambdas are assignable to anything
|
||||
c.explicitC = m => m;
|
||||
c.explicitThis = m => m;
|
||||
c.explicitProperty = m => m;
|
||||
|
||||
// this inside lambdas refer to outer scope
|
||||
// the outer-scoped lambda at top-level is still just `any`
|
||||
c.explicitC = m => m + this.n;
|
||||
c.explicitThis = m => m + this.n;
|
||||
c.explicitProperty = m => m + this.n;
|
||||
|
||||
//NOTE: this=C here, I guess?
|
||||
c.explicitThis = explicitCFunction;
|
||||
c.explicitThis = function(this: C, m: number) { return this.n + m };
|
||||
|
||||
// this:any compatibility
|
||||
c.explicitC = function(m: number) { return this.n + m };
|
||||
c.explicitProperty = function(m: number) { return this.n + m };
|
||||
c.explicitThis = function(m: number) { return this.n + m };
|
||||
c.implicitThis = function(m: number) { return this.n + m };
|
||||
c.implicitThis = reconstructed.implicitThis;
|
||||
|
||||
c.explicitC = function(this: B, m: number) { return this.n + m };
|
||||
|
||||
// this:void compatibility
|
||||
c.explicitVoid = n => n;
|
||||
|
||||
// class-based assignability
|
||||
class Base1 {
|
||||
x: number;
|
||||
public implicit(): number { return this.x; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
static implicitStatic(): number { return this.y; }
|
||||
static explicitStatic(this: typeof Base1): number { return this.y; }
|
||||
static y: number;
|
||||
|
||||
}
|
||||
class Derived1 extends Base1 {
|
||||
y: number
|
||||
}
|
||||
class Base2 {
|
||||
y: number
|
||||
implicit(): number { return this.y; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
}
|
||||
class Derived2 extends Base2 {
|
||||
x: number
|
||||
}
|
||||
let b1 = new Base1();
|
||||
let b2 = new Base2();
|
||||
let d1 = new Derived1();
|
||||
let d2 = new Derived2();
|
||||
d2.implicit = d1.implicit // ok, 'x' and 'y' in { x, y } (d assignable to f and vice versa)
|
||||
d1.implicit = d2.implicit // ok, 'x' and 'y' in { x, y } (f assignable to d and vice versa)
|
||||
|
||||
// bivariance-allowed cases
|
||||
d1.implicit = b2.implicit // ok, 'y' in D: { x, y } (d assignable e)
|
||||
d2.implicit = d1.explicit // ok, 'y' in { x, y } (c assignable to f)
|
||||
b1.implicit = d2.implicit // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
b1.explicit = d2.implicit // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
|
||||
////// use this-type for construction with new ////
|
||||
function InterfaceThis(this: I) {
|
||||
this.a = 12;
|
||||
}
|
||||
function LiteralTypeThis(this: {x: string}) {
|
||||
this.x = "ok";
|
||||
}
|
||||
function AnyThis(this: any) {
|
||||
this.x = "ok";
|
||||
}
|
||||
let interfaceThis = new InterfaceThis();
|
||||
let literalTypeThis = new LiteralTypeThis();
|
||||
let anyThis = new AnyThis();
|
||||
|
||||
//// type parameter inference ////
|
||||
declare var f: {
|
||||
(this: void, x: number): number,
|
||||
call<U>(this: (...argArray: any[]) => U, ...argArray: any[]): U;
|
||||
};
|
||||
let n: number = f.call(12);
|
||||
|
||||
function missingTypeIsImplicitAny(this, a: number) { return a; }
|
||||
|
||||
//// [thisTypeInFunctions.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 _this = this;
|
||||
// body checking
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.explicitThis = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.implicitThis = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.explicitC = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.explicitProperty = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.explicitVoid = function (m) {
|
||||
return m + 1;
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return D;
|
||||
}(C));
|
||||
var B = (function () {
|
||||
function B() {
|
||||
}
|
||||
return B;
|
||||
}());
|
||||
function explicitStructural(x) {
|
||||
return x + this.y;
|
||||
}
|
||||
function justThis() {
|
||||
return this.y;
|
||||
}
|
||||
function implicitThis(n) {
|
||||
return 12;
|
||||
}
|
||||
var impl = {
|
||||
a: 12,
|
||||
explicitVoid2: function () { return _this.a; },
|
||||
explicitVoid1: function () { return 12; },
|
||||
explicitStructural: function () {
|
||||
return this.a;
|
||||
},
|
||||
explicitInterface: function () {
|
||||
return this.a;
|
||||
},
|
||||
explicitThis: function () {
|
||||
return this.a;
|
||||
},
|
||||
implicitMethod: function () {
|
||||
return this.a;
|
||||
},
|
||||
implicitFunction: function () { return _this.a; }
|
||||
};
|
||||
impl.explicitVoid1 = function () { return 12; };
|
||||
impl.explicitVoid2 = function () { return 12; };
|
||||
impl.explicitStructural = function () { return this.a; };
|
||||
impl.explicitInterface = function () { return this.a; };
|
||||
impl.explicitStructural = function () { return 12; };
|
||||
impl.explicitInterface = function () { return 12; };
|
||||
impl.explicitThis = function () { return this.a; };
|
||||
impl.implicitMethod = function () { return this.a; };
|
||||
impl.implicitMethod = function () { return 12; };
|
||||
impl.implicitFunction = function () { return _this.a; }; // ok, this: any because it refers to some outer object (window?)
|
||||
// parameter checking
|
||||
var ok = { y: 12, f: explicitStructural };
|
||||
var implicitAnyOk = { notSpecified: 12, f: implicitThis };
|
||||
ok.f(13);
|
||||
implicitThis(12);
|
||||
implicitAnyOk.f(12);
|
||||
var c = new C();
|
||||
var d = new D();
|
||||
var ripped = c.explicitC;
|
||||
c.explicitC(12);
|
||||
c.explicitProperty(12);
|
||||
c.explicitThis(12);
|
||||
c.implicitThis(12);
|
||||
d.explicitC(12);
|
||||
d.explicitProperty(12);
|
||||
d.explicitThis(12);
|
||||
d.implicitThis(12);
|
||||
var reconstructed = {
|
||||
n: 12,
|
||||
explicitThis: c.explicitThis,
|
||||
implicitThis: c.implicitThis,
|
||||
explicitC: c.explicitC,
|
||||
explicitProperty: c.explicitProperty,
|
||||
explicitVoid: c.explicitVoid
|
||||
};
|
||||
reconstructed.explicitProperty(11);
|
||||
reconstructed.implicitThis(11);
|
||||
// assignment checking
|
||||
var unboundToSpecified = function (x) { return x + _this.y; }; // ok, this:any
|
||||
var specifiedToSpecified = explicitStructural;
|
||||
var anyToSpecified = function (x) { return x + 12; };
|
||||
var unspecifiedLambda = function (x) { return x + 12; };
|
||||
var specifiedLambda = function (x) { return x + 12; };
|
||||
var unspecifiedLambdaToSpecified = unspecifiedLambda;
|
||||
var specifiedLambdaToSpecified = specifiedLambda;
|
||||
var explicitCFunction;
|
||||
var explicitPropertyFunction;
|
||||
c.explicitC = explicitCFunction;
|
||||
c.explicitC = function (m) { return this.n + m; };
|
||||
c.explicitProperty = explicitPropertyFunction;
|
||||
c.explicitProperty = function (m) { return this.n + m; };
|
||||
c.explicitProperty = reconstructed.explicitProperty;
|
||||
// lambdas are assignable to anything
|
||||
c.explicitC = function (m) { return m; };
|
||||
c.explicitThis = function (m) { return m; };
|
||||
c.explicitProperty = function (m) { return m; };
|
||||
// this inside lambdas refer to outer scope
|
||||
// the outer-scoped lambda at top-level is still just `any`
|
||||
c.explicitC = function (m) { return m + _this.n; };
|
||||
c.explicitThis = function (m) { return m + _this.n; };
|
||||
c.explicitProperty = function (m) { return m + _this.n; };
|
||||
//NOTE: this=C here, I guess?
|
||||
c.explicitThis = explicitCFunction;
|
||||
c.explicitThis = function (m) { return this.n + m; };
|
||||
// this:any compatibility
|
||||
c.explicitC = function (m) { return this.n + m; };
|
||||
c.explicitProperty = function (m) { return this.n + m; };
|
||||
c.explicitThis = function (m) { return this.n + m; };
|
||||
c.implicitThis = function (m) { return this.n + m; };
|
||||
c.implicitThis = reconstructed.implicitThis;
|
||||
c.explicitC = function (m) { return this.n + m; };
|
||||
// this:void compatibility
|
||||
c.explicitVoid = function (n) { return n; };
|
||||
// class-based assignability
|
||||
var Base1 = (function () {
|
||||
function Base1() {
|
||||
}
|
||||
Base1.prototype.implicit = function () { return this.x; };
|
||||
Base1.prototype.explicit = function () { return this.x; };
|
||||
Base1.implicitStatic = function () { return this.y; };
|
||||
Base1.explicitStatic = function () { return this.y; };
|
||||
return Base1;
|
||||
}());
|
||||
var Derived1 = (function (_super) {
|
||||
__extends(Derived1, _super);
|
||||
function Derived1() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return Derived1;
|
||||
}(Base1));
|
||||
var Base2 = (function () {
|
||||
function Base2() {
|
||||
}
|
||||
Base2.prototype.implicit = function () { return this.y; };
|
||||
Base2.prototype.explicit = function () { return this.x; };
|
||||
return Base2;
|
||||
}());
|
||||
var Derived2 = (function (_super) {
|
||||
__extends(Derived2, _super);
|
||||
function Derived2() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return Derived2;
|
||||
}(Base2));
|
||||
var b1 = new Base1();
|
||||
var b2 = new Base2();
|
||||
var d1 = new Derived1();
|
||||
var d2 = new Derived2();
|
||||
d2.implicit = d1.implicit; // ok, 'x' and 'y' in { x, y } (d assignable to f and vice versa)
|
||||
d1.implicit = d2.implicit; // ok, 'x' and 'y' in { x, y } (f assignable to d and vice versa)
|
||||
// bivariance-allowed cases
|
||||
d1.implicit = b2.implicit; // ok, 'y' in D: { x, y } (d assignable e)
|
||||
d2.implicit = d1.explicit; // ok, 'y' in { x, y } (c assignable to f)
|
||||
b1.implicit = d2.implicit; // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
b1.explicit = d2.implicit; // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
////// use this-type for construction with new ////
|
||||
function InterfaceThis() {
|
||||
this.a = 12;
|
||||
}
|
||||
function LiteralTypeThis() {
|
||||
this.x = "ok";
|
||||
}
|
||||
function AnyThis() {
|
||||
this.x = "ok";
|
||||
}
|
||||
var interfaceThis = new InterfaceThis();
|
||||
var literalTypeThis = new LiteralTypeThis();
|
||||
var anyThis = new AnyThis();
|
||||
var n = f.call(12);
|
||||
function missingTypeIsImplicitAny(a) { return a; }
|
||||
862
tests/baselines/reference/thisTypeInFunctions.symbols
Normal file
862
tests/baselines/reference/thisTypeInFunctions.symbols
Normal file
@ -0,0 +1,862 @@
|
||||
=== tests/cases/conformance/types/thisType/thisTypeInFunctions.ts ===
|
||||
// body checking
|
||||
class C {
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
|
||||
n: number;
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
|
||||
explicitThis(this: this, m: number): number {
|
||||
>explicitThis : Symbol(explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 3, 17))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 3, 28))
|
||||
|
||||
return this.n + m;
|
||||
>this.n : Symbol(n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 3, 28))
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 6, 17))
|
||||
|
||||
return this.n + m;
|
||||
>this.n : Symbol(n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 6, 17))
|
||||
}
|
||||
explicitC(this: C, m: number): number {
|
||||
>explicitC : Symbol(explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 9, 14))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 9, 22))
|
||||
|
||||
return this.n + m;
|
||||
>this.n : Symbol(n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 9, 22))
|
||||
}
|
||||
explicitProperty(this: {n: number}, m: number): number {
|
||||
>explicitProperty : Symbol(explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 12, 21))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 12, 28))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 12, 39))
|
||||
|
||||
return this.n + m;
|
||||
>this.n : Symbol(n, Decl(thisTypeInFunctions.ts, 12, 28))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 12, 26))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 12, 28))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 12, 39))
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
>explicitVoid : Symbol(explicitVoid, Decl(thisTypeInFunctions.ts, 14, 5))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 15, 17))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 15, 28))
|
||||
|
||||
return m + 1;
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 15, 28))
|
||||
}
|
||||
}
|
||||
class D extends C { }
|
||||
>D : Symbol(D, Decl(thisTypeInFunctions.ts, 18, 1))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
|
||||
class B {
|
||||
>B : Symbol(B, Decl(thisTypeInFunctions.ts, 19, 21))
|
||||
|
||||
n: number;
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 20, 9))
|
||||
}
|
||||
interface I {
|
||||
>I : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
|
||||
a: number;
|
||||
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
|
||||
explicitVoid1(this: void): number;
|
||||
>explicitVoid1 : Symbol(explicitVoid1, Decl(thisTypeInFunctions.ts, 24, 14))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 25, 18))
|
||||
|
||||
explicitVoid2(this: void): number;
|
||||
>explicitVoid2 : Symbol(explicitVoid2, Decl(thisTypeInFunctions.ts, 25, 38))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 26, 18))
|
||||
|
||||
explicitStructural(this: {a: number}): number;
|
||||
>explicitStructural : Symbol(explicitStructural, Decl(thisTypeInFunctions.ts, 26, 38))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 27, 23))
|
||||
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 27, 30))
|
||||
|
||||
explicitInterface(this: I): number;
|
||||
>explicitInterface : Symbol(explicitInterface, Decl(thisTypeInFunctions.ts, 27, 50))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 28, 22))
|
||||
>I : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
|
||||
explicitThis(this: this): number;
|
||||
>explicitThis : Symbol(explicitThis, Decl(thisTypeInFunctions.ts, 28, 39))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 29, 17))
|
||||
|
||||
implicitMethod(): number;
|
||||
>implicitMethod : Symbol(implicitMethod, Decl(thisTypeInFunctions.ts, 29, 37))
|
||||
|
||||
implicitFunction: () => number;
|
||||
>implicitFunction : Symbol(implicitFunction, Decl(thisTypeInFunctions.ts, 30, 29))
|
||||
}
|
||||
function explicitStructural(this: { y: number }, x: number): number {
|
||||
>explicitStructural : Symbol(explicitStructural, Decl(thisTypeInFunctions.ts, 32, 1))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 33, 28))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 33, 35))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 33, 48))
|
||||
|
||||
return x + this.y;
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 33, 48))
|
||||
>this.y : Symbol(y, Decl(thisTypeInFunctions.ts, 33, 35))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 33, 33))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 33, 35))
|
||||
}
|
||||
function justThis(this: { y: number }): number {
|
||||
>justThis : Symbol(justThis, Decl(thisTypeInFunctions.ts, 35, 1))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 36, 18))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 36, 25))
|
||||
|
||||
return this.y;
|
||||
>this.y : Symbol(y, Decl(thisTypeInFunctions.ts, 36, 25))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 36, 23))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 36, 25))
|
||||
}
|
||||
function implicitThis(n: number): number {
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 38, 1))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 39, 22))
|
||||
|
||||
return 12;
|
||||
}
|
||||
let impl: I = {
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>I : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
|
||||
a: 12,
|
||||
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 42, 15))
|
||||
|
||||
explicitVoid2: () => this.a, // ok, this: any because it refers to some outer object (window?)
|
||||
>explicitVoid2 : Symbol(explicitVoid2, Decl(thisTypeInFunctions.ts, 43, 10))
|
||||
|
||||
explicitVoid1() { return 12; },
|
||||
>explicitVoid1 : Symbol(explicitVoid1, Decl(thisTypeInFunctions.ts, 44, 32))
|
||||
|
||||
explicitStructural() {
|
||||
>explicitStructural : Symbol(explicitStructural, Decl(thisTypeInFunctions.ts, 45, 35))
|
||||
|
||||
return this.a;
|
||||
>this.a : Symbol(a, Decl(thisTypeInFunctions.ts, 27, 30))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 27, 28))
|
||||
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 27, 30))
|
||||
|
||||
},
|
||||
explicitInterface() {
|
||||
>explicitInterface : Symbol(explicitInterface, Decl(thisTypeInFunctions.ts, 48, 6))
|
||||
|
||||
return this.a;
|
||||
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
|
||||
},
|
||||
explicitThis() {
|
||||
>explicitThis : Symbol(explicitThis, Decl(thisTypeInFunctions.ts, 51, 6))
|
||||
|
||||
return this.a;
|
||||
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
|
||||
},
|
||||
implicitMethod() {
|
||||
>implicitMethod : Symbol(implicitMethod, Decl(thisTypeInFunctions.ts, 54, 6))
|
||||
|
||||
return this.a;
|
||||
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
|
||||
},
|
||||
implicitFunction: () => this.a, // ok, this: any because it refers to some outer object (window?)
|
||||
>implicitFunction : Symbol(implicitFunction, Decl(thisTypeInFunctions.ts, 57, 6))
|
||||
}
|
||||
impl.explicitVoid1 = function () { return 12; };
|
||||
>impl.explicitVoid1 : Symbol(I.explicitVoid1, Decl(thisTypeInFunctions.ts, 24, 14))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>explicitVoid1 : Symbol(I.explicitVoid1, Decl(thisTypeInFunctions.ts, 24, 14))
|
||||
|
||||
impl.explicitVoid2 = () => 12;
|
||||
>impl.explicitVoid2 : Symbol(I.explicitVoid2, Decl(thisTypeInFunctions.ts, 25, 38))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>explicitVoid2 : Symbol(I.explicitVoid2, Decl(thisTypeInFunctions.ts, 25, 38))
|
||||
|
||||
impl.explicitStructural = function() { return this.a; };
|
||||
>impl.explicitStructural : Symbol(I.explicitStructural, Decl(thisTypeInFunctions.ts, 26, 38))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>explicitStructural : Symbol(I.explicitStructural, Decl(thisTypeInFunctions.ts, 26, 38))
|
||||
>this.a : Symbol(a, Decl(thisTypeInFunctions.ts, 27, 30))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 27, 28))
|
||||
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 27, 30))
|
||||
|
||||
impl.explicitInterface = function() { return this.a; };
|
||||
>impl.explicitInterface : Symbol(I.explicitInterface, Decl(thisTypeInFunctions.ts, 27, 50))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>explicitInterface : Symbol(I.explicitInterface, Decl(thisTypeInFunctions.ts, 27, 50))
|
||||
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
|
||||
impl.explicitStructural = () => 12;
|
||||
>impl.explicitStructural : Symbol(I.explicitStructural, Decl(thisTypeInFunctions.ts, 26, 38))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>explicitStructural : Symbol(I.explicitStructural, Decl(thisTypeInFunctions.ts, 26, 38))
|
||||
|
||||
impl.explicitInterface = () => 12;
|
||||
>impl.explicitInterface : Symbol(I.explicitInterface, Decl(thisTypeInFunctions.ts, 27, 50))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>explicitInterface : Symbol(I.explicitInterface, Decl(thisTypeInFunctions.ts, 27, 50))
|
||||
|
||||
impl.explicitThis = function () { return this.a; };
|
||||
>impl.explicitThis : Symbol(I.explicitThis, Decl(thisTypeInFunctions.ts, 28, 39))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>explicitThis : Symbol(I.explicitThis, Decl(thisTypeInFunctions.ts, 28, 39))
|
||||
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
|
||||
impl.implicitMethod = function () { return this.a; };
|
||||
>impl.implicitMethod : Symbol(I.implicitMethod, Decl(thisTypeInFunctions.ts, 29, 37))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>implicitMethod : Symbol(I.implicitMethod, Decl(thisTypeInFunctions.ts, 29, 37))
|
||||
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
|
||||
impl.implicitMethod = () => 12;
|
||||
>impl.implicitMethod : Symbol(I.implicitMethod, Decl(thisTypeInFunctions.ts, 29, 37))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>implicitMethod : Symbol(I.implicitMethod, Decl(thisTypeInFunctions.ts, 29, 37))
|
||||
|
||||
impl.implicitFunction = () => this.a; // ok, this: any because it refers to some outer object (window?)
|
||||
>impl.implicitFunction : Symbol(I.implicitFunction, Decl(thisTypeInFunctions.ts, 30, 29))
|
||||
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 42, 3))
|
||||
>implicitFunction : Symbol(I.implicitFunction, Decl(thisTypeInFunctions.ts, 30, 29))
|
||||
|
||||
// parameter checking
|
||||
let ok: {y: number, f: (this: { y: number }, x: number) => number} = { y: 12, f: explicitStructural };
|
||||
>ok : Symbol(ok, Decl(thisTypeInFunctions.ts, 71, 3))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 71, 9))
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 71, 19))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 71, 24))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 71, 31))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 71, 44))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 71, 70))
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 71, 77))
|
||||
>explicitStructural : Symbol(explicitStructural, Decl(thisTypeInFunctions.ts, 32, 1))
|
||||
|
||||
let implicitAnyOk: {notSpecified: number, f: (x: number) => number} = { notSpecified: 12, f: implicitThis };
|
||||
>implicitAnyOk : Symbol(implicitAnyOk, Decl(thisTypeInFunctions.ts, 72, 3))
|
||||
>notSpecified : Symbol(notSpecified, Decl(thisTypeInFunctions.ts, 72, 20))
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 72, 41))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 72, 46))
|
||||
>notSpecified : Symbol(notSpecified, Decl(thisTypeInFunctions.ts, 72, 71))
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 72, 89))
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 38, 1))
|
||||
|
||||
ok.f(13);
|
||||
>ok.f : Symbol(f, Decl(thisTypeInFunctions.ts, 71, 19))
|
||||
>ok : Symbol(ok, Decl(thisTypeInFunctions.ts, 71, 3))
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 71, 19))
|
||||
|
||||
implicitThis(12);
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 38, 1))
|
||||
|
||||
implicitAnyOk.f(12);
|
||||
>implicitAnyOk.f : Symbol(f, Decl(thisTypeInFunctions.ts, 72, 41))
|
||||
>implicitAnyOk : Symbol(implicitAnyOk, Decl(thisTypeInFunctions.ts, 72, 3))
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 72, 41))
|
||||
|
||||
let c = new C();
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
|
||||
let d = new D();
|
||||
>d : Symbol(d, Decl(thisTypeInFunctions.ts, 78, 3))
|
||||
>D : Symbol(D, Decl(thisTypeInFunctions.ts, 18, 1))
|
||||
|
||||
let ripped = c.explicitC;
|
||||
>ripped : Symbol(ripped, Decl(thisTypeInFunctions.ts, 79, 3))
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
|
||||
c.explicitC(12);
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
|
||||
c.explicitProperty(12);
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
|
||||
c.explicitThis(12);
|
||||
>c.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
|
||||
c.implicitThis(12);
|
||||
>c.implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
|
||||
d.explicitC(12);
|
||||
>d.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>d : Symbol(d, Decl(thisTypeInFunctions.ts, 78, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
|
||||
d.explicitProperty(12);
|
||||
>d.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>d : Symbol(d, Decl(thisTypeInFunctions.ts, 78, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
|
||||
d.explicitThis(12);
|
||||
>d.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>d : Symbol(d, Decl(thisTypeInFunctions.ts, 78, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
|
||||
d.implicitThis(12);
|
||||
>d.implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>d : Symbol(d, Decl(thisTypeInFunctions.ts, 78, 3))
|
||||
>implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
|
||||
let reconstructed: {
|
||||
>reconstructed : Symbol(reconstructed, Decl(thisTypeInFunctions.ts, 88, 3))
|
||||
|
||||
n: number,
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 88, 20))
|
||||
|
||||
explicitThis(this: C, m: number): number, // note: this: this is not allowed in an object literal type.
|
||||
>explicitThis : Symbol(explicitThis, Decl(thisTypeInFunctions.ts, 89, 14))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 90, 17))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 90, 25))
|
||||
|
||||
implicitThis(m: number): number,
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 90, 45))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 91, 17))
|
||||
|
||||
explicitC(this: C, m: number): number,
|
||||
>explicitC : Symbol(explicitC, Decl(thisTypeInFunctions.ts, 91, 36))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 92, 14))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 92, 22))
|
||||
|
||||
explicitProperty: (this: {n : number}, m: number) => number,
|
||||
>explicitProperty : Symbol(explicitProperty, Decl(thisTypeInFunctions.ts, 92, 42))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 93, 23))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 93, 30))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 93, 42))
|
||||
|
||||
explicitVoid(this: void, m: number): number,
|
||||
>explicitVoid : Symbol(explicitVoid, Decl(thisTypeInFunctions.ts, 93, 64))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 94, 17))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 94, 28))
|
||||
|
||||
} = {
|
||||
n: 12,
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 95, 5))
|
||||
|
||||
explicitThis: c.explicitThis,
|
||||
>explicitThis : Symbol(explicitThis, Decl(thisTypeInFunctions.ts, 96, 10))
|
||||
>c.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
|
||||
implicitThis: c.implicitThis,
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 97, 33))
|
||||
>c.implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
|
||||
explicitC: c.explicitC,
|
||||
>explicitC : Symbol(explicitC, Decl(thisTypeInFunctions.ts, 98, 33))
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
|
||||
explicitProperty: c.explicitProperty,
|
||||
>explicitProperty : Symbol(explicitProperty, Decl(thisTypeInFunctions.ts, 99, 27))
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
|
||||
explicitVoid: c.explicitVoid
|
||||
>explicitVoid : Symbol(explicitVoid, Decl(thisTypeInFunctions.ts, 100, 41))
|
||||
>c.explicitVoid : Symbol(C.explicitVoid, Decl(thisTypeInFunctions.ts, 14, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitVoid : Symbol(C.explicitVoid, Decl(thisTypeInFunctions.ts, 14, 5))
|
||||
|
||||
};
|
||||
reconstructed.explicitProperty(11);
|
||||
>reconstructed.explicitProperty : Symbol(explicitProperty, Decl(thisTypeInFunctions.ts, 92, 42))
|
||||
>reconstructed : Symbol(reconstructed, Decl(thisTypeInFunctions.ts, 88, 3))
|
||||
>explicitProperty : Symbol(explicitProperty, Decl(thisTypeInFunctions.ts, 92, 42))
|
||||
|
||||
reconstructed.implicitThis(11);
|
||||
>reconstructed.implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 90, 45))
|
||||
>reconstructed : Symbol(reconstructed, Decl(thisTypeInFunctions.ts, 88, 3))
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 90, 45))
|
||||
|
||||
// assignment checking
|
||||
let unboundToSpecified: (this: { y: number }, x: number) => number = x => x + this.y; // ok, this:any
|
||||
>unboundToSpecified : Symbol(unboundToSpecified, Decl(thisTypeInFunctions.ts, 107, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 107, 25))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 107, 32))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 107, 45))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 107, 68))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 107, 68))
|
||||
|
||||
let specifiedToSpecified: (this: {y: number}, x: number) => number = explicitStructural;
|
||||
>specifiedToSpecified : Symbol(specifiedToSpecified, Decl(thisTypeInFunctions.ts, 108, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 108, 27))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 108, 34))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 108, 45))
|
||||
>explicitStructural : Symbol(explicitStructural, Decl(thisTypeInFunctions.ts, 32, 1))
|
||||
|
||||
let anyToSpecified: (this: { y: number }, x: number) => number = function(x: number): number { return x + 12; };
|
||||
>anyToSpecified : Symbol(anyToSpecified, Decl(thisTypeInFunctions.ts, 109, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 109, 21))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 109, 28))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 109, 41))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 109, 74))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 109, 74))
|
||||
|
||||
let unspecifiedLambda: (x: number) => number = x => x + 12;
|
||||
>unspecifiedLambda : Symbol(unspecifiedLambda, Decl(thisTypeInFunctions.ts, 111, 3))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 111, 24))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 111, 46))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 111, 46))
|
||||
|
||||
let specifiedLambda: (this: void, x: number) => number = x => x + 12;
|
||||
>specifiedLambda : Symbol(specifiedLambda, Decl(thisTypeInFunctions.ts, 112, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 112, 22))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 112, 33))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 112, 56))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 112, 56))
|
||||
|
||||
let unspecifiedLambdaToSpecified: (this: {y: number}, x: number) => number = unspecifiedLambda;
|
||||
>unspecifiedLambdaToSpecified : Symbol(unspecifiedLambdaToSpecified, Decl(thisTypeInFunctions.ts, 113, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 113, 35))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 113, 42))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 113, 53))
|
||||
>unspecifiedLambda : Symbol(unspecifiedLambda, Decl(thisTypeInFunctions.ts, 111, 3))
|
||||
|
||||
let specifiedLambdaToSpecified: (this: {y: number}, x: number) => number = specifiedLambda;
|
||||
>specifiedLambdaToSpecified : Symbol(specifiedLambdaToSpecified, Decl(thisTypeInFunctions.ts, 114, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 114, 33))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 114, 40))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 114, 51))
|
||||
>specifiedLambda : Symbol(specifiedLambda, Decl(thisTypeInFunctions.ts, 112, 3))
|
||||
|
||||
|
||||
let explicitCFunction: (this: C, m: number) => number;
|
||||
>explicitCFunction : Symbol(explicitCFunction, Decl(thisTypeInFunctions.ts, 117, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 117, 24))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 117, 32))
|
||||
|
||||
let explicitPropertyFunction: (this: {n: number}, m: number) => number;
|
||||
>explicitPropertyFunction : Symbol(explicitPropertyFunction, Decl(thisTypeInFunctions.ts, 118, 3))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 118, 31))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 118, 38))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 118, 49))
|
||||
|
||||
c.explicitC = explicitCFunction;
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>explicitCFunction : Symbol(explicitCFunction, Decl(thisTypeInFunctions.ts, 117, 3))
|
||||
|
||||
c.explicitC = function(this: C, m: number) { return this.n + m };
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 120, 23))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 120, 31))
|
||||
>this.n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 120, 31))
|
||||
|
||||
c.explicitProperty = explicitPropertyFunction;
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>explicitPropertyFunction : Symbol(explicitPropertyFunction, Decl(thisTypeInFunctions.ts, 118, 3))
|
||||
|
||||
c.explicitProperty = function(this: {n: number}, m: number) { return this.n + m };
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 122, 30))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 122, 37))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 122, 48))
|
||||
>this.n : Symbol(n, Decl(thisTypeInFunctions.ts, 122, 37))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 122, 35))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 122, 37))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 122, 48))
|
||||
|
||||
c.explicitProperty = reconstructed.explicitProperty;
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>reconstructed.explicitProperty : Symbol(explicitProperty, Decl(thisTypeInFunctions.ts, 92, 42))
|
||||
>reconstructed : Symbol(reconstructed, Decl(thisTypeInFunctions.ts, 88, 3))
|
||||
>explicitProperty : Symbol(explicitProperty, Decl(thisTypeInFunctions.ts, 92, 42))
|
||||
|
||||
// lambdas are assignable to anything
|
||||
c.explicitC = m => m;
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 126, 13))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 126, 13))
|
||||
|
||||
c.explicitThis = m => m;
|
||||
>c.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 127, 16))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 127, 16))
|
||||
|
||||
c.explicitProperty = m => m;
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 128, 20))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 128, 20))
|
||||
|
||||
// this inside lambdas refer to outer scope
|
||||
// the outer-scoped lambda at top-level is still just `any`
|
||||
c.explicitC = m => m + this.n;
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 132, 13))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 132, 13))
|
||||
|
||||
c.explicitThis = m => m + this.n;
|
||||
>c.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 133, 16))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 133, 16))
|
||||
|
||||
c.explicitProperty = m => m + this.n;
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 134, 20))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 134, 20))
|
||||
|
||||
//NOTE: this=C here, I guess?
|
||||
c.explicitThis = explicitCFunction;
|
||||
>c.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>explicitCFunction : Symbol(explicitCFunction, Decl(thisTypeInFunctions.ts, 117, 3))
|
||||
|
||||
c.explicitThis = function(this: C, m: number) { return this.n + m };
|
||||
>c.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 138, 26))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 138, 34))
|
||||
>this.n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 138, 34))
|
||||
|
||||
// this:any compatibility
|
||||
c.explicitC = function(m: number) { return this.n + m };
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 141, 23))
|
||||
>this.n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 141, 23))
|
||||
|
||||
c.explicitProperty = function(m: number) { return this.n + m };
|
||||
>c.explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 142, 30))
|
||||
>this.n : Symbol(n, Decl(thisTypeInFunctions.ts, 12, 28))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 12, 26))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 12, 28))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 142, 30))
|
||||
|
||||
c.explicitThis = function(m: number) { return this.n + m };
|
||||
>c.explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 2, 14))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 143, 26))
|
||||
>this.n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 143, 26))
|
||||
|
||||
c.implicitThis = function(m: number) { return this.n + m };
|
||||
>c.implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 144, 26))
|
||||
>this.n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 0, 0))
|
||||
>n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 1, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 144, 26))
|
||||
|
||||
c.implicitThis = reconstructed.implicitThis;
|
||||
>c.implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>implicitThis : Symbol(C.implicitThis, Decl(thisTypeInFunctions.ts, 5, 5))
|
||||
>reconstructed.implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 90, 45))
|
||||
>reconstructed : Symbol(reconstructed, Decl(thisTypeInFunctions.ts, 88, 3))
|
||||
>implicitThis : Symbol(implicitThis, Decl(thisTypeInFunctions.ts, 90, 45))
|
||||
|
||||
c.explicitC = function(this: B, m: number) { return this.n + m };
|
||||
>c.explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 147, 23))
|
||||
>B : Symbol(B, Decl(thisTypeInFunctions.ts, 19, 21))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 147, 31))
|
||||
>this.n : Symbol(B.n, Decl(thisTypeInFunctions.ts, 20, 9))
|
||||
>this : Symbol(B, Decl(thisTypeInFunctions.ts, 19, 21))
|
||||
>n : Symbol(B.n, Decl(thisTypeInFunctions.ts, 20, 9))
|
||||
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 147, 31))
|
||||
|
||||
// this:void compatibility
|
||||
c.explicitVoid = n => n;
|
||||
>c.explicitVoid : Symbol(C.explicitVoid, Decl(thisTypeInFunctions.ts, 14, 5))
|
||||
>c : Symbol(c, Decl(thisTypeInFunctions.ts, 77, 3))
|
||||
>explicitVoid : Symbol(C.explicitVoid, Decl(thisTypeInFunctions.ts, 14, 5))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 150, 16))
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 150, 16))
|
||||
|
||||
// class-based assignability
|
||||
class Base1 {
|
||||
>Base1 : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
|
||||
x: number;
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 153, 13))
|
||||
|
||||
public implicit(): number { return this.x; }
|
||||
>implicit : Symbol(implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>this.x : Symbol(x, Decl(thisTypeInFunctions.ts, 153, 13))
|
||||
>this : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 153, 13))
|
||||
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
>explicit : Symbol(explicit, Decl(thisTypeInFunctions.ts, 155, 48))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 156, 13))
|
||||
>Base1 : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>this.x : Symbol(x, Decl(thisTypeInFunctions.ts, 153, 13))
|
||||
>this : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 153, 13))
|
||||
|
||||
static implicitStatic(): number { return this.y; }
|
||||
>implicitStatic : Symbol(Base1.implicitStatic, Decl(thisTypeInFunctions.ts, 156, 52))
|
||||
>this.y : Symbol(Base1.y, Decl(thisTypeInFunctions.ts, 158, 72))
|
||||
>this : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>y : Symbol(Base1.y, Decl(thisTypeInFunctions.ts, 158, 72))
|
||||
|
||||
static explicitStatic(this: typeof Base1): number { return this.y; }
|
||||
>explicitStatic : Symbol(Base1.explicitStatic, Decl(thisTypeInFunctions.ts, 157, 54))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 158, 26))
|
||||
>Base1 : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>this.y : Symbol(Base1.y, Decl(thisTypeInFunctions.ts, 158, 72))
|
||||
>this : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>y : Symbol(Base1.y, Decl(thisTypeInFunctions.ts, 158, 72))
|
||||
|
||||
static y: number;
|
||||
>y : Symbol(Base1.y, Decl(thisTypeInFunctions.ts, 158, 72))
|
||||
|
||||
}
|
||||
class Derived1 extends Base1 {
|
||||
>Derived1 : Symbol(Derived1, Decl(thisTypeInFunctions.ts, 161, 1))
|
||||
>Base1 : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
|
||||
y: number
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 162, 30))
|
||||
}
|
||||
class Base2 {
|
||||
>Base2 : Symbol(Base2, Decl(thisTypeInFunctions.ts, 164, 1))
|
||||
|
||||
y: number
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 165, 13))
|
||||
|
||||
implicit(): number { return this.y; }
|
||||
>implicit : Symbol(implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>this.y : Symbol(y, Decl(thisTypeInFunctions.ts, 165, 13))
|
||||
>this : Symbol(Base2, Decl(thisTypeInFunctions.ts, 164, 1))
|
||||
>y : Symbol(y, Decl(thisTypeInFunctions.ts, 165, 13))
|
||||
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
>explicit : Symbol(explicit, Decl(thisTypeInFunctions.ts, 167, 41))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 168, 13))
|
||||
>Base1 : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>this.x : Symbol(Base1.x, Decl(thisTypeInFunctions.ts, 153, 13))
|
||||
>this : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
>x : Symbol(Base1.x, Decl(thisTypeInFunctions.ts, 153, 13))
|
||||
}
|
||||
class Derived2 extends Base2 {
|
||||
>Derived2 : Symbol(Derived2, Decl(thisTypeInFunctions.ts, 169, 1))
|
||||
>Base2 : Symbol(Base2, Decl(thisTypeInFunctions.ts, 164, 1))
|
||||
|
||||
x: number
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 170, 30))
|
||||
}
|
||||
let b1 = new Base1();
|
||||
>b1 : Symbol(b1, Decl(thisTypeInFunctions.ts, 173, 3))
|
||||
>Base1 : Symbol(Base1, Decl(thisTypeInFunctions.ts, 150, 24))
|
||||
|
||||
let b2 = new Base2();
|
||||
>b2 : Symbol(b2, Decl(thisTypeInFunctions.ts, 174, 3))
|
||||
>Base2 : Symbol(Base2, Decl(thisTypeInFunctions.ts, 164, 1))
|
||||
|
||||
let d1 = new Derived1();
|
||||
>d1 : Symbol(d1, Decl(thisTypeInFunctions.ts, 175, 3))
|
||||
>Derived1 : Symbol(Derived1, Decl(thisTypeInFunctions.ts, 161, 1))
|
||||
|
||||
let d2 = new Derived2();
|
||||
>d2 : Symbol(d2, Decl(thisTypeInFunctions.ts, 176, 3))
|
||||
>Derived2 : Symbol(Derived2, Decl(thisTypeInFunctions.ts, 169, 1))
|
||||
|
||||
d2.implicit = d1.implicit // ok, 'x' and 'y' in { x, y } (d assignable to f and vice versa)
|
||||
>d2.implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>d2 : Symbol(d2, Decl(thisTypeInFunctions.ts, 176, 3))
|
||||
>implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>d1.implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>d1 : Symbol(d1, Decl(thisTypeInFunctions.ts, 175, 3))
|
||||
>implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
|
||||
d1.implicit = d2.implicit // ok, 'x' and 'y' in { x, y } (f assignable to d and vice versa)
|
||||
>d1.implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>d1 : Symbol(d1, Decl(thisTypeInFunctions.ts, 175, 3))
|
||||
>implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>d2.implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>d2 : Symbol(d2, Decl(thisTypeInFunctions.ts, 176, 3))
|
||||
>implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
|
||||
// bivariance-allowed cases
|
||||
d1.implicit = b2.implicit // ok, 'y' in D: { x, y } (d assignable e)
|
||||
>d1.implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>d1 : Symbol(d1, Decl(thisTypeInFunctions.ts, 175, 3))
|
||||
>implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>b2.implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>b2 : Symbol(b2, Decl(thisTypeInFunctions.ts, 174, 3))
|
||||
>implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
|
||||
d2.implicit = d1.explicit // ok, 'y' in { x, y } (c assignable to f)
|
||||
>d2.implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>d2 : Symbol(d2, Decl(thisTypeInFunctions.ts, 176, 3))
|
||||
>implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>d1.explicit : Symbol(Base1.explicit, Decl(thisTypeInFunctions.ts, 155, 48))
|
||||
>d1 : Symbol(d1, Decl(thisTypeInFunctions.ts, 175, 3))
|
||||
>explicit : Symbol(Base1.explicit, Decl(thisTypeInFunctions.ts, 155, 48))
|
||||
|
||||
b1.implicit = d2.implicit // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
>b1.implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>b1 : Symbol(b1, Decl(thisTypeInFunctions.ts, 173, 3))
|
||||
>implicit : Symbol(Base1.implicit, Decl(thisTypeInFunctions.ts, 154, 14))
|
||||
>d2.implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>d2 : Symbol(d2, Decl(thisTypeInFunctions.ts, 176, 3))
|
||||
>implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
|
||||
b1.explicit = d2.implicit // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
>b1.explicit : Symbol(Base1.explicit, Decl(thisTypeInFunctions.ts, 155, 48))
|
||||
>b1 : Symbol(b1, Decl(thisTypeInFunctions.ts, 173, 3))
|
||||
>explicit : Symbol(Base1.explicit, Decl(thisTypeInFunctions.ts, 155, 48))
|
||||
>d2.implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
>d2 : Symbol(d2, Decl(thisTypeInFunctions.ts, 176, 3))
|
||||
>implicit : Symbol(Base2.implicit, Decl(thisTypeInFunctions.ts, 166, 13))
|
||||
|
||||
////// use this-type for construction with new ////
|
||||
function InterfaceThis(this: I) {
|
||||
>InterfaceThis : Symbol(InterfaceThis, Decl(thisTypeInFunctions.ts, 184, 25))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 187, 23))
|
||||
>I : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
|
||||
this.a = 12;
|
||||
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 22, 1))
|
||||
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 23, 13))
|
||||
}
|
||||
function LiteralTypeThis(this: {x: string}) {
|
||||
>LiteralTypeThis : Symbol(LiteralTypeThis, Decl(thisTypeInFunctions.ts, 189, 1))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 190, 25))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 190, 32))
|
||||
|
||||
this.x = "ok";
|
||||
>this.x : Symbol(x, Decl(thisTypeInFunctions.ts, 190, 32))
|
||||
>this : Symbol(, Decl(thisTypeInFunctions.ts, 190, 30))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 190, 32))
|
||||
}
|
||||
function AnyThis(this: any) {
|
||||
>AnyThis : Symbol(AnyThis, Decl(thisTypeInFunctions.ts, 192, 1))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 193, 17))
|
||||
|
||||
this.x = "ok";
|
||||
}
|
||||
let interfaceThis = new InterfaceThis();
|
||||
>interfaceThis : Symbol(interfaceThis, Decl(thisTypeInFunctions.ts, 196, 3))
|
||||
>InterfaceThis : Symbol(InterfaceThis, Decl(thisTypeInFunctions.ts, 184, 25))
|
||||
|
||||
let literalTypeThis = new LiteralTypeThis();
|
||||
>literalTypeThis : Symbol(literalTypeThis, Decl(thisTypeInFunctions.ts, 197, 3))
|
||||
>LiteralTypeThis : Symbol(LiteralTypeThis, Decl(thisTypeInFunctions.ts, 189, 1))
|
||||
|
||||
let anyThis = new AnyThis();
|
||||
>anyThis : Symbol(anyThis, Decl(thisTypeInFunctions.ts, 198, 3))
|
||||
>AnyThis : Symbol(AnyThis, Decl(thisTypeInFunctions.ts, 192, 1))
|
||||
|
||||
//// type parameter inference ////
|
||||
declare var f: {
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 201, 11))
|
||||
|
||||
(this: void, x: number): number,
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 202, 5))
|
||||
>x : Symbol(x, Decl(thisTypeInFunctions.ts, 202, 16))
|
||||
|
||||
call<U>(this: (...argArray: any[]) => U, ...argArray: any[]): U;
|
||||
>call : Symbol(call, Decl(thisTypeInFunctions.ts, 202, 36))
|
||||
>U : Symbol(U, Decl(thisTypeInFunctions.ts, 203, 9))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 203, 12))
|
||||
>argArray : Symbol(argArray, Decl(thisTypeInFunctions.ts, 203, 19))
|
||||
>U : Symbol(U, Decl(thisTypeInFunctions.ts, 203, 9))
|
||||
>argArray : Symbol(argArray, Decl(thisTypeInFunctions.ts, 203, 44))
|
||||
>U : Symbol(U, Decl(thisTypeInFunctions.ts, 203, 9))
|
||||
|
||||
};
|
||||
let n: number = f.call(12);
|
||||
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 205, 3))
|
||||
>f.call : Symbol(call, Decl(thisTypeInFunctions.ts, 202, 36))
|
||||
>f : Symbol(f, Decl(thisTypeInFunctions.ts, 201, 11))
|
||||
>call : Symbol(call, Decl(thisTypeInFunctions.ts, 202, 36))
|
||||
|
||||
function missingTypeIsImplicitAny(this, a: number) { return a; }
|
||||
>missingTypeIsImplicitAny : Symbol(missingTypeIsImplicitAny, Decl(thisTypeInFunctions.ts, 205, 27))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 207, 34))
|
||||
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 207, 39))
|
||||
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 207, 39))
|
||||
|
||||
1037
tests/baselines/reference/thisTypeInFunctions.types
Normal file
1037
tests/baselines/reference/thisTypeInFunctions.types
Normal file
File diff suppressed because it is too large
Load Diff
509
tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt
Normal file
509
tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt
Normal file
@ -0,0 +1,509 @@
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(16,15): error TS2339: Property 'n' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(44,21): error TS2339: Property 'a' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(55,49): error TS2339: Property 'a' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(58,1): error TS2345: Argument of type 'void' is not assignable to parameter of type '{ a: number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(60,1): error TS2345: Argument of type 'void' is not assignable to parameter of type 'I'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(62,1): error TS2345: Argument of type 'void' is not assignable to parameter of type 'I'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(67,21): error TS2339: Property 'notFound' does not exist on type '{ y: number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(70,21): error TS2339: Property 'notSpecified' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(74,21): error TS2339: Property 'notSpecified' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(76,79): error TS2322: Type '{ y: number; explicitStructural: (this: { y: number; }, x: number) => number; }' is not assignable to type '{ y: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
Object literal may only specify known properties, and 'explicitStructural' does not exist in type '{ y: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(77,97): error TS2322: Type '{ y: string; explicitStructural: (this: { y: number; }, x: number) => number; }' is not assignable to type '{ y: string; f: (this: { y: number; }, x: number) => number; }'.
|
||||
Object literal may only specify known properties, and 'explicitStructural' does not exist in type '{ y: string; f: (this: { y: number; }, x: number) => number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(78,110): error TS2322: Type '{ wrongName: number; explicitStructural: (this: { y: number; }, x: number) => number; }' is not assignable to type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
Object literal may only specify known properties, and 'explicitStructural' does not exist in type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(80,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(81,6): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(82,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(83,1): error TS2345: Argument of type '{ y: string; f: (this: { y: number; }, x: number) => number; }' is not assignable to parameter of type '{ y: number; }'.
|
||||
Types of property 'y' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(84,1): error TS2345: Argument of type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }' is not assignable to parameter of type '{ y: number; }'.
|
||||
Property 'y' is missing in type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(87,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(88,13): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(89,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(90,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(91,16): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(92,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(93,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(94,16): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(95,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(96,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(97,20): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(98,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(101,5): error TS2322: Type '(this: { y: number; }, x: number) => number' is not assignable to type '(x: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'void' is not assignable to type '{ y: number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(124,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'C' is not assignable to type 'D'.
|
||||
Property 'x' is missing in type 'C'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(125,1): error TS2322: Type '(this: { x: number; }, m: number) => number' is not assignable to type '(this: { n: number; }, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type '{ n: number; }' is not assignable to type '{ x: number; }'.
|
||||
Property 'x' is missing in type '{ n: number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(127,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'C' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(128,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'C' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(129,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'C' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(130,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'C' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(131,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'C' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(132,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'C' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(133,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: { n: number; }, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type '{ n: number; }' is not assignable to type 'D'.
|
||||
Property 'x' is missing in type '{ n: number; }'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(134,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: { n: number; }, m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type '{ n: number; }' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(135,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(136,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'void' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(137,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'void' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(138,1): error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'void' is not assignable to type 'D'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(146,51): error TS2339: Property 'x' does not exist on type 'typeof Base1'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(147,69): error TS2339: Property 'x' does not exist on type 'typeof Base1'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(167,1): error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'Base1' is not assignable to type 'Base2'.
|
||||
Property 'y' is missing in type 'Base1'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(168,1): error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'Base1' is not assignable to type 'Base2'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(170,1): error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
||||
Types of parameters 'this' and 'this' are incompatible.
|
||||
Type 'Base1' is not assignable to type 'Base2'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(179,16): error TS2671: A function that is called with the 'new' keyword cannot have a 'this' type that is void.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(180,24): error TS2671: A function that is called with the 'new' keyword cannot have a 'this' type that is void.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(184,30): error TS2332: 'this' cannot be referenced in current location.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(185,26): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(185,30): error TS1005: ',' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(185,57): error TS2339: Property 'n' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(186,20): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(186,23): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(186,27): error TS1005: ',' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(186,54): error TS2339: Property 'n' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(187,23): error TS1005: ',' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(187,24): error TS1138: Parameter declaration expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(187,51): error TS2339: Property 'n' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(188,28): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(188,32): error TS1005: ',' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(188,59): error TS2339: Property 'n' does not exist on type 'void'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(189,30): error TS1005: ',' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(189,32): error TS1138: Parameter declaration expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(189,39): error TS1005: ';' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(189,40): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(189,42): error TS2304: Cannot find name 'number'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(189,49): error TS1005: ';' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(192,1): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(192,29): error TS2304: Cannot find name 'm'.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(192,32): error TS1005: ';' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(192,35): error TS2304: Cannot find name 'm'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (75 errors) ====
|
||||
class C {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitC(this: C, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitProperty(this: {n: number}, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return this.n + m; // 'n' doesn't exist on type 'void'.
|
||||
~
|
||||
!!! error TS2339: Property 'n' does not exist on type 'void'.
|
||||
}
|
||||
}
|
||||
class D {
|
||||
x: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
explicitD(this: D, m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
implicitD(m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
}
|
||||
interface I {
|
||||
a: number;
|
||||
explicitVoid1(this: void): number;
|
||||
explicitVoid2(this: void): number;
|
||||
explicitStructural(this: {a: number}): number;
|
||||
explicitInterface(this: I): number;
|
||||
explicitThis(this: this): number; // TODO: Allow `this` types for interfaces
|
||||
implicitMethod(): number;
|
||||
implicitFunction: () => number;
|
||||
}
|
||||
let impl: I = {
|
||||
a: 12,
|
||||
explicitVoid1() {
|
||||
return this.a; // error, no 'a' in 'void'
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'void'.
|
||||
},
|
||||
explicitVoid2: () => this.a, // ok, `this:any` because it refers to an outer object
|
||||
explicitStructural: () => 12,
|
||||
explicitInterface: () => 12,
|
||||
explicitThis() {
|
||||
return this.a;
|
||||
},
|
||||
implicitMethod() {
|
||||
return this.a; // ok, I.a: number
|
||||
},
|
||||
implicitFunction: function () { return this.a; } // TODO: error 'a' not found in 'void'
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'void'.
|
||||
}
|
||||
let implExplicitStructural = impl.explicitStructural;
|
||||
implExplicitStructural(); // error, no 'a' in 'void'
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'void' is not assignable to parameter of type '{ a: number; }'.
|
||||
let implExplicitInterface = impl.explicitInterface;
|
||||
implExplicitInterface(); // error, no 'a' in 'void'
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'void' is not assignable to parameter of type 'I'.
|
||||
let implImplicitMethod = impl.implicitMethod;
|
||||
implImplicitMethod(); // error, no 'a' in 'void'
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'void' is not assignable to parameter of type 'I'.
|
||||
function explicitStructural(this: { y: number }, x: number): number {
|
||||
return x + this.y;
|
||||
}
|
||||
function propertyName(this: { y: number }, x: number): number {
|
||||
return x + this.notFound;
|
||||
~~~~~~~~
|
||||
!!! error TS2339: Property 'notFound' does not exist on type '{ y: number; }'.
|
||||
}
|
||||
function voidThisSpecified(this: void, x: number): number {
|
||||
return x + this.notSpecified;
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2339: Property 'notSpecified' does not exist on type 'void'.
|
||||
}
|
||||
function noThisSpecified(x: number): number {
|
||||
// this:void unless loose-this is on
|
||||
return x + this.notSpecified;
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2339: Property 'notSpecified' does not exist on type 'void'.
|
||||
}
|
||||
let ok: {y: number, f: (this: { y: number }, x: number) => number} = { y: 12, explicitStructural };
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ y: number; explicitStructural: (this: { y: number; }, x: number) => number; }' is not assignable to type '{ y: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'explicitStructural' does not exist in type '{ y: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
let wrongPropertyType: {y: string, f: (this: { y: number }, x: number) => number} = { y: 'foo', explicitStructural };
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ y: string; explicitStructural: (this: { y: number; }, x: number) => number; }' is not assignable to type '{ y: string; f: (this: { y: number; }, x: number) => number; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'explicitStructural' does not exist in type '{ y: string; f: (this: { y: number; }, x: number) => number; }'.
|
||||
let wrongPropertyName: {wrongName: number, f: (this: { y: number }, x: number) => number} = { wrongName: 12, explicitStructural };
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ wrongName: number; explicitStructural: (this: { y: number; }, x: number) => number; }' is not assignable to type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'explicitStructural' does not exist in type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
|
||||
ok.f(); // not enough arguments
|
||||
~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
ok.f('wrong type');
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
ok.f(13, 'too many arguments');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
wrongPropertyType.f(13);
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '{ y: string; f: (this: { y: number; }, x: number) => number; }' is not assignable to parameter of type '{ y: number; }'.
|
||||
!!! error TS2345: Types of property 'y' are incompatible.
|
||||
!!! error TS2345: Type 'string' is not assignable to type 'number'.
|
||||
wrongPropertyName.f(13);
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }' is not assignable to parameter of type '{ y: number; }'.
|
||||
!!! error TS2345: Property 'y' is missing in type '{ wrongName: number; f: (this: { y: number; }, x: number) => number; }'.
|
||||
|
||||
let c = new C();
|
||||
c.explicitC(); // not enough arguments
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
c.explicitC('wrong type');
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
c.explicitC(13, 'too many arguments');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
c.explicitThis(); // not enough arguments
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
c.explicitThis('wrong type 2');
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
c.explicitThis(14, 'too many arguments 2');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
c.implicitThis(); // not enough arguments
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
c.implicitThis('wrong type 2');
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
c.implicitThis(14, 'too many arguments 2');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
c.explicitProperty(); // not enough arguments
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
c.explicitProperty('wrong type 3');
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
|
||||
c.explicitProperty(15, 'too many arguments 3');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
|
||||
// oops, this triggers contextual typing, which needs to be updated to understand that =>'s `this` is void.
|
||||
let specifiedToImplicitVoid: (x: number) => number = explicitStructural;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: { y: number; }, x: number) => number' is not assignable to type '(x: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'void' is not assignable to type '{ y: number; }'.
|
||||
|
||||
let reconstructed: {
|
||||
n: number,
|
||||
explicitThis(this: C, m: number): number, // note: this: this is not allowed in an object literal type.
|
||||
implicitThis(m: number): number,
|
||||
explicitC(this: C, m: number): number,
|
||||
explicitProperty: (this: {n : number}, m: number) => number,
|
||||
explicitVoid(this: void, m: number): number,
|
||||
} = {
|
||||
n: 12,
|
||||
explicitThis: c.explicitThis,
|
||||
implicitThis: c.implicitThis, // error not assignable -- c.this:c<this> not assignable to this:void.
|
||||
explicitC: c.explicitC,
|
||||
explicitProperty: c.explicitProperty,
|
||||
explicitVoid: c.explicitVoid
|
||||
};;
|
||||
|
||||
// lambdas have this: void for assignability purposes (and this unbound (free) for body checking)
|
||||
let d = new D();
|
||||
let explicitXProperty: (this: { x: number }, m: number) => number;
|
||||
|
||||
// from differing object types
|
||||
c.explicitC = function(this: D, m: number) { return this.x + m };
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'D'.
|
||||
!!! error TS2322: Property 'x' is missing in type 'C'.
|
||||
c.explicitProperty = explicitXProperty;
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: { x: number; }, m: number) => number' is not assignable to type '(this: { n: number; }, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type '{ n: number; }' is not assignable to type '{ x: number; }'.
|
||||
!!! error TS2322: Property 'x' is missing in type '{ n: number; }'.
|
||||
|
||||
c.explicitC = d.implicitD;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'D'.
|
||||
c.explicitC = d.explicitD;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'D'.
|
||||
c.explicitC = d.explicitThis;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'D'.
|
||||
c.explicitThis = d.implicitD;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'D'.
|
||||
c.explicitThis = d.explicitD;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'D'.
|
||||
c.explicitThis = d.explicitThis;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'C' is not assignable to type 'D'.
|
||||
c.explicitProperty = d.explicitD;
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: { n: number; }, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type '{ n: number; }' is not assignable to type 'D'.
|
||||
!!! error TS2322: Property 'x' is missing in type '{ n: number; }'.
|
||||
c.explicitProperty = d.implicitD;
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: { n: number; }, m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type '{ n: number; }' is not assignable to type 'D'.
|
||||
c.explicitThis = d.explicitThis;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(this: C, m: number) => number'.
|
||||
c.explicitVoid = d.implicitD;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'D'.
|
||||
c.explicitVoid = d.explicitD;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'D'.
|
||||
c.explicitVoid = d.explicitThis;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: D, m: number) => number' is not assignable to type '(m: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'D'.
|
||||
|
||||
/// class-based implicit assignability (with inheritance!) ///
|
||||
|
||||
class Base1 {
|
||||
x: number
|
||||
public implicit(): number { return this.x; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
static implicitStatic(): number { return this.x; }
|
||||
~
|
||||
!!! error TS2339: Property 'x' does not exist on type 'typeof Base1'.
|
||||
static explicitStatic(this: typeof Base1): number { return this.x; }
|
||||
~
|
||||
!!! error TS2339: Property 'x' does not exist on type 'typeof Base1'.
|
||||
}
|
||||
class Derived1 extends Base1 {
|
||||
y: number
|
||||
}
|
||||
class Base2 {
|
||||
y: number
|
||||
implicit(): number { return this.y; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
}
|
||||
class Derived2 extends Base2 {
|
||||
x: number
|
||||
}
|
||||
|
||||
|
||||
let b1 = new Base1();
|
||||
let d1 = new Derived1();
|
||||
let b2 = new Base2();
|
||||
let d2 = new Derived2();
|
||||
|
||||
b1.implicit = b2.implicit // error, 'this.y' not in C: { x } (c assignable to e)
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'Base1' is not assignable to type 'Base2'.
|
||||
!!! error TS2322: Property 'y' is missing in type 'Base1'.
|
||||
b1.explicit = b2.implicit // error, 'y' not in C: { x } (c assignable to e)
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'Base1' is not assignable to type 'Base2'.
|
||||
|
||||
d1.explicit = b2.implicit // error, 'y' not in C: { x } (c assignable to e)
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(this: Base2) => number' is not assignable to type '(this: Base1) => number'.
|
||||
!!! error TS2322: Types of parameters 'this' and 'this' are incompatible.
|
||||
!!! error TS2322: Type 'Base1' is not assignable to type 'Base2'.
|
||||
|
||||
////// use this-type for construction with new ////
|
||||
function VoidThis(this: void) {
|
||||
|
||||
}
|
||||
function ImplicitVoidThis() {
|
||||
|
||||
}
|
||||
let voidThis = new VoidThis();
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2671: A function that is called with the 'new' keyword cannot have a 'this' type that is void.
|
||||
let implicitVoidThis = new ImplicitVoidThis();
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2671: A function that is called with the 'new' keyword cannot have a 'this' type that is void.
|
||||
|
||||
|
||||
///// parse errors /////
|
||||
function notFirst(a: number, this: C): number { return this.n; }
|
||||
~~~~~~~
|
||||
!!! error TS2332: 'this' cannot be referenced in current location.
|
||||
function modifiers(async this: C): number { return this.n; }
|
||||
~~~~
|
||||
!!! error TS1003: Identifier expected.
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~
|
||||
!!! error TS2339: Property 'n' does not exist on type 'void'.
|
||||
function restParam(...this: C): number { return this.n; }
|
||||
~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
~~~~
|
||||
!!! error TS1003: Identifier expected.
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~
|
||||
!!! error TS2339: Property 'n' does not exist on type 'void'.
|
||||
function optional(this?: C): number { return this.n; }
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~
|
||||
!!! error TS1138: Parameter declaration expected.
|
||||
~
|
||||
!!! error TS2339: Property 'n' does not exist on type 'void'.
|
||||
function decorated(@deco() this: C): number { return this.n; }
|
||||
~~~~
|
||||
!!! error TS1003: Identifier expected.
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~
|
||||
!!! error TS2339: Property 'n' does not exist on type 'void'.
|
||||
function initializer(this: C = new C()): number { return this.n; }
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
~~~
|
||||
!!! error TS1138: Parameter declaration expected.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'number'.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
|
||||
// can't name parameters 'this' in a lambda.
|
||||
c.explicitProperty = (this, m) => m + this.n;
|
||||
~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'm'.
|
||||
~~
|
||||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'm'.
|
||||
|
||||
386
tests/baselines/reference/thisTypeInFunctionsNegative.js
Normal file
386
tests/baselines/reference/thisTypeInFunctionsNegative.js
Normal file
@ -0,0 +1,386 @@
|
||||
//// [thisTypeInFunctionsNegative.ts]
|
||||
class C {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitC(this: C, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitProperty(this: {n: number}, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return this.n + m; // 'n' doesn't exist on type 'void'.
|
||||
}
|
||||
}
|
||||
class D {
|
||||
x: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
explicitD(this: D, m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
implicitD(m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
}
|
||||
interface I {
|
||||
a: number;
|
||||
explicitVoid1(this: void): number;
|
||||
explicitVoid2(this: void): number;
|
||||
explicitStructural(this: {a: number}): number;
|
||||
explicitInterface(this: I): number;
|
||||
explicitThis(this: this): number; // TODO: Allow `this` types for interfaces
|
||||
implicitMethod(): number;
|
||||
implicitFunction: () => number;
|
||||
}
|
||||
let impl: I = {
|
||||
a: 12,
|
||||
explicitVoid1() {
|
||||
return this.a; // error, no 'a' in 'void'
|
||||
},
|
||||
explicitVoid2: () => this.a, // ok, `this:any` because it refers to an outer object
|
||||
explicitStructural: () => 12,
|
||||
explicitInterface: () => 12,
|
||||
explicitThis() {
|
||||
return this.a;
|
||||
},
|
||||
implicitMethod() {
|
||||
return this.a; // ok, I.a: number
|
||||
},
|
||||
implicitFunction: function () { return this.a; } // TODO: error 'a' not found in 'void'
|
||||
}
|
||||
let implExplicitStructural = impl.explicitStructural;
|
||||
implExplicitStructural(); // error, no 'a' in 'void'
|
||||
let implExplicitInterface = impl.explicitInterface;
|
||||
implExplicitInterface(); // error, no 'a' in 'void'
|
||||
let implImplicitMethod = impl.implicitMethod;
|
||||
implImplicitMethod(); // error, no 'a' in 'void'
|
||||
function explicitStructural(this: { y: number }, x: number): number {
|
||||
return x + this.y;
|
||||
}
|
||||
function propertyName(this: { y: number }, x: number): number {
|
||||
return x + this.notFound;
|
||||
}
|
||||
function voidThisSpecified(this: void, x: number): number {
|
||||
return x + this.notSpecified;
|
||||
}
|
||||
function noThisSpecified(x: number): number {
|
||||
// this:void unless loose-this is on
|
||||
return x + this.notSpecified;
|
||||
}
|
||||
let ok: {y: number, f: (this: { y: number }, x: number) => number} = { y: 12, explicitStructural };
|
||||
let wrongPropertyType: {y: string, f: (this: { y: number }, x: number) => number} = { y: 'foo', explicitStructural };
|
||||
let wrongPropertyName: {wrongName: number, f: (this: { y: number }, x: number) => number} = { wrongName: 12, explicitStructural };
|
||||
|
||||
ok.f(); // not enough arguments
|
||||
ok.f('wrong type');
|
||||
ok.f(13, 'too many arguments');
|
||||
wrongPropertyType.f(13);
|
||||
wrongPropertyName.f(13);
|
||||
|
||||
let c = new C();
|
||||
c.explicitC(); // not enough arguments
|
||||
c.explicitC('wrong type');
|
||||
c.explicitC(13, 'too many arguments');
|
||||
c.explicitThis(); // not enough arguments
|
||||
c.explicitThis('wrong type 2');
|
||||
c.explicitThis(14, 'too many arguments 2');
|
||||
c.implicitThis(); // not enough arguments
|
||||
c.implicitThis('wrong type 2');
|
||||
c.implicitThis(14, 'too many arguments 2');
|
||||
c.explicitProperty(); // not enough arguments
|
||||
c.explicitProperty('wrong type 3');
|
||||
c.explicitProperty(15, 'too many arguments 3');
|
||||
|
||||
// oops, this triggers contextual typing, which needs to be updated to understand that =>'s `this` is void.
|
||||
let specifiedToImplicitVoid: (x: number) => number = explicitStructural;
|
||||
|
||||
let reconstructed: {
|
||||
n: number,
|
||||
explicitThis(this: C, m: number): number, // note: this: this is not allowed in an object literal type.
|
||||
implicitThis(m: number): number,
|
||||
explicitC(this: C, m: number): number,
|
||||
explicitProperty: (this: {n : number}, m: number) => number,
|
||||
explicitVoid(this: void, m: number): number,
|
||||
} = {
|
||||
n: 12,
|
||||
explicitThis: c.explicitThis,
|
||||
implicitThis: c.implicitThis, // error not assignable -- c.this:c<this> not assignable to this:void.
|
||||
explicitC: c.explicitC,
|
||||
explicitProperty: c.explicitProperty,
|
||||
explicitVoid: c.explicitVoid
|
||||
};;
|
||||
|
||||
// lambdas have this: void for assignability purposes (and this unbound (free) for body checking)
|
||||
let d = new D();
|
||||
let explicitXProperty: (this: { x: number }, m: number) => number;
|
||||
|
||||
// from differing object types
|
||||
c.explicitC = function(this: D, m: number) { return this.x + m };
|
||||
c.explicitProperty = explicitXProperty;
|
||||
|
||||
c.explicitC = d.implicitD;
|
||||
c.explicitC = d.explicitD;
|
||||
c.explicitC = d.explicitThis;
|
||||
c.explicitThis = d.implicitD;
|
||||
c.explicitThis = d.explicitD;
|
||||
c.explicitThis = d.explicitThis;
|
||||
c.explicitProperty = d.explicitD;
|
||||
c.explicitProperty = d.implicitD;
|
||||
c.explicitThis = d.explicitThis;
|
||||
c.explicitVoid = d.implicitD;
|
||||
c.explicitVoid = d.explicitD;
|
||||
c.explicitVoid = d.explicitThis;
|
||||
|
||||
/// class-based implicit assignability (with inheritance!) ///
|
||||
|
||||
class Base1 {
|
||||
x: number
|
||||
public implicit(): number { return this.x; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
static implicitStatic(): number { return this.x; }
|
||||
static explicitStatic(this: typeof Base1): number { return this.x; }
|
||||
}
|
||||
class Derived1 extends Base1 {
|
||||
y: number
|
||||
}
|
||||
class Base2 {
|
||||
y: number
|
||||
implicit(): number { return this.y; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
}
|
||||
class Derived2 extends Base2 {
|
||||
x: number
|
||||
}
|
||||
|
||||
|
||||
let b1 = new Base1();
|
||||
let d1 = new Derived1();
|
||||
let b2 = new Base2();
|
||||
let d2 = new Derived2();
|
||||
|
||||
b1.implicit = b2.implicit // error, 'this.y' not in C: { x } (c assignable to e)
|
||||
b1.explicit = b2.implicit // error, 'y' not in C: { x } (c assignable to e)
|
||||
|
||||
d1.explicit = b2.implicit // error, 'y' not in C: { x } (c assignable to e)
|
||||
|
||||
////// use this-type for construction with new ////
|
||||
function VoidThis(this: void) {
|
||||
|
||||
}
|
||||
function ImplicitVoidThis() {
|
||||
|
||||
}
|
||||
let voidThis = new VoidThis();
|
||||
let implicitVoidThis = new ImplicitVoidThis();
|
||||
|
||||
|
||||
///// parse errors /////
|
||||
function notFirst(a: number, this: C): number { return this.n; }
|
||||
function modifiers(async this: C): number { return this.n; }
|
||||
function restParam(...this: C): number { return this.n; }
|
||||
function optional(this?: C): number { return this.n; }
|
||||
function decorated(@deco() this: C): number { return this.n; }
|
||||
function initializer(this: C = new C()): number { return this.n; }
|
||||
|
||||
// can't name parameters 'this' in a lambda.
|
||||
c.explicitProperty = (this, m) => m + this.n;
|
||||
|
||||
|
||||
//// [thisTypeInFunctionsNegative.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 _this = this;
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.explicitThis = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.implicitThis = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.explicitC = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.explicitProperty = function (m) {
|
||||
return this.n + m;
|
||||
};
|
||||
C.prototype.explicitVoid = function (m) {
|
||||
return this.n + m; // 'n' doesn't exist on type 'void'.
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
var D = (function () {
|
||||
function D() {
|
||||
}
|
||||
D.prototype.explicitThis = function (m) {
|
||||
return this.x + m;
|
||||
};
|
||||
D.prototype.explicitD = function (m) {
|
||||
return this.x + m;
|
||||
};
|
||||
D.prototype.implicitD = function (m) {
|
||||
return this.x + m;
|
||||
};
|
||||
return D;
|
||||
}());
|
||||
var impl = {
|
||||
a: 12,
|
||||
explicitVoid1: function () {
|
||||
return this.a; // error, no 'a' in 'void'
|
||||
},
|
||||
explicitVoid2: function () { return _this.a; },
|
||||
explicitStructural: function () { return 12; },
|
||||
explicitInterface: function () { return 12; },
|
||||
explicitThis: function () {
|
||||
return this.a;
|
||||
},
|
||||
implicitMethod: function () {
|
||||
return this.a; // ok, I.a: number
|
||||
},
|
||||
implicitFunction: function () { return this.a; } // TODO: error 'a' not found in 'void'
|
||||
};
|
||||
var implExplicitStructural = impl.explicitStructural;
|
||||
implExplicitStructural(); // error, no 'a' in 'void'
|
||||
var implExplicitInterface = impl.explicitInterface;
|
||||
implExplicitInterface(); // error, no 'a' in 'void'
|
||||
var implImplicitMethod = impl.implicitMethod;
|
||||
implImplicitMethod(); // error, no 'a' in 'void'
|
||||
function explicitStructural(x) {
|
||||
return x + this.y;
|
||||
}
|
||||
function propertyName(x) {
|
||||
return x + this.notFound;
|
||||
}
|
||||
function voidThisSpecified(x) {
|
||||
return x + this.notSpecified;
|
||||
}
|
||||
function noThisSpecified(x) {
|
||||
// this:void unless loose-this is on
|
||||
return x + this.notSpecified;
|
||||
}
|
||||
var ok = { y: 12, explicitStructural: explicitStructural };
|
||||
var wrongPropertyType = { y: 'foo', explicitStructural: explicitStructural };
|
||||
var wrongPropertyName = { wrongName: 12, explicitStructural: explicitStructural };
|
||||
ok.f(); // not enough arguments
|
||||
ok.f('wrong type');
|
||||
ok.f(13, 'too many arguments');
|
||||
wrongPropertyType.f(13);
|
||||
wrongPropertyName.f(13);
|
||||
var c = new C();
|
||||
c.explicitC(); // not enough arguments
|
||||
c.explicitC('wrong type');
|
||||
c.explicitC(13, 'too many arguments');
|
||||
c.explicitThis(); // not enough arguments
|
||||
c.explicitThis('wrong type 2');
|
||||
c.explicitThis(14, 'too many arguments 2');
|
||||
c.implicitThis(); // not enough arguments
|
||||
c.implicitThis('wrong type 2');
|
||||
c.implicitThis(14, 'too many arguments 2');
|
||||
c.explicitProperty(); // not enough arguments
|
||||
c.explicitProperty('wrong type 3');
|
||||
c.explicitProperty(15, 'too many arguments 3');
|
||||
// oops, this triggers contextual typing, which needs to be updated to understand that =>'s `this` is void.
|
||||
var specifiedToImplicitVoid = explicitStructural;
|
||||
var reconstructed = {
|
||||
n: 12,
|
||||
explicitThis: c.explicitThis,
|
||||
implicitThis: c.implicitThis,
|
||||
explicitC: c.explicitC,
|
||||
explicitProperty: c.explicitProperty,
|
||||
explicitVoid: c.explicitVoid
|
||||
};
|
||||
;
|
||||
// lambdas have this: void for assignability purposes (and this unbound (free) for body checking)
|
||||
var d = new D();
|
||||
var explicitXProperty;
|
||||
// from differing object types
|
||||
c.explicitC = function (m) { return this.x + m; };
|
||||
c.explicitProperty = explicitXProperty;
|
||||
c.explicitC = d.implicitD;
|
||||
c.explicitC = d.explicitD;
|
||||
c.explicitC = d.explicitThis;
|
||||
c.explicitThis = d.implicitD;
|
||||
c.explicitThis = d.explicitD;
|
||||
c.explicitThis = d.explicitThis;
|
||||
c.explicitProperty = d.explicitD;
|
||||
c.explicitProperty = d.implicitD;
|
||||
c.explicitThis = d.explicitThis;
|
||||
c.explicitVoid = d.implicitD;
|
||||
c.explicitVoid = d.explicitD;
|
||||
c.explicitVoid = d.explicitThis;
|
||||
/// class-based implicit assignability (with inheritance!) ///
|
||||
var Base1 = (function () {
|
||||
function Base1() {
|
||||
}
|
||||
Base1.prototype.implicit = function () { return this.x; };
|
||||
Base1.prototype.explicit = function () { return this.x; };
|
||||
Base1.implicitStatic = function () { return this.x; };
|
||||
Base1.explicitStatic = function () { return this.x; };
|
||||
return Base1;
|
||||
}());
|
||||
var Derived1 = (function (_super) {
|
||||
__extends(Derived1, _super);
|
||||
function Derived1() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return Derived1;
|
||||
}(Base1));
|
||||
var Base2 = (function () {
|
||||
function Base2() {
|
||||
}
|
||||
Base2.prototype.implicit = function () { return this.y; };
|
||||
Base2.prototype.explicit = function () { return this.x; };
|
||||
return Base2;
|
||||
}());
|
||||
var Derived2 = (function (_super) {
|
||||
__extends(Derived2, _super);
|
||||
function Derived2() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return Derived2;
|
||||
}(Base2));
|
||||
var b1 = new Base1();
|
||||
var d1 = new Derived1();
|
||||
var b2 = new Base2();
|
||||
var d2 = new Derived2();
|
||||
b1.implicit = b2.implicit; // error, 'this.y' not in C: { x } (c assignable to e)
|
||||
b1.explicit = b2.implicit; // error, 'y' not in C: { x } (c assignable to e)
|
||||
d1.explicit = b2.implicit; // error, 'y' not in C: { x } (c assignable to e)
|
||||
////// use this-type for construction with new ////
|
||||
function VoidThis() {
|
||||
}
|
||||
function ImplicitVoidThis() {
|
||||
}
|
||||
var voidThis = new VoidThis();
|
||||
var implicitVoidThis = new ImplicitVoidThis();
|
||||
///// parse errors /////
|
||||
function notFirst(a, this) { return this.n; }
|
||||
function modifiers(, C) {
|
||||
if ( === void 0) { = this; }
|
||||
return this.n;
|
||||
}
|
||||
function restParam(, C) { return this.n; }
|
||||
function optional(C) { return this.n; }
|
||||
function decorated(, C) {
|
||||
if ( === void 0) { = this; }
|
||||
return this.n;
|
||||
}
|
||||
new C();
|
||||
number;
|
||||
{
|
||||
return this.n;
|
||||
}
|
||||
// can't name parameters 'this' in a lambda.
|
||||
c.explicitProperty = (this, m);
|
||||
m + this.n;
|
||||
@ -0,0 +1,34 @@
|
||||
interface I {
|
||||
explicitThis(this: this, m: number): number;
|
||||
}
|
||||
interface Unused {
|
||||
implicitNoThis(m: number): number;
|
||||
}
|
||||
class C implements I {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return m + 1;
|
||||
}
|
||||
}
|
||||
let c = new C();
|
||||
c.explicitVoid = c.explicitThis; // error, 'void' is missing everything
|
||||
let o = {
|
||||
explicitThis: function (m) { return m },
|
||||
implicitThis(m: number): number { return m }
|
||||
};
|
||||
let i: I = o;
|
||||
let x = i.explicitThis;
|
||||
let n = x(12); // callee:void doesn't match this:I
|
||||
let u: Unused;
|
||||
let y = u.implicitNoThis;
|
||||
n = y(12); // ok, callee:void matches this:any
|
||||
c.explicitVoid = c.implicitThis // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.implicitThis; // ok, implicitThis(this:any)
|
||||
o.implicitThis = c.explicitThis; // ok, implicitThis(this:any) is assignable to explicitThis(this: this)
|
||||
o.implicitThis = i.explicitThis;
|
||||
209
tests/cases/conformance/types/thisType/thisTypeInFunctions.ts
Normal file
209
tests/cases/conformance/types/thisType/thisTypeInFunctions.ts
Normal file
@ -0,0 +1,209 @@
|
||||
// @strictThis: true
|
||||
// body checking
|
||||
class C {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitC(this: C, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitProperty(this: {n: number}, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return m + 1;
|
||||
}
|
||||
}
|
||||
class D extends C { }
|
||||
class B {
|
||||
n: number;
|
||||
}
|
||||
interface I {
|
||||
a: number;
|
||||
explicitVoid1(this: void): number;
|
||||
explicitVoid2(this: void): number;
|
||||
explicitStructural(this: {a: number}): number;
|
||||
explicitInterface(this: I): number;
|
||||
explicitThis(this: this): number;
|
||||
implicitMethod(): number;
|
||||
implicitFunction: () => number;
|
||||
}
|
||||
function explicitStructural(this: { y: number }, x: number): number {
|
||||
return x + this.y;
|
||||
}
|
||||
function justThis(this: { y: number }): number {
|
||||
return this.y;
|
||||
}
|
||||
function implicitThis(n: number): number {
|
||||
return 12;
|
||||
}
|
||||
let impl: I = {
|
||||
a: 12,
|
||||
explicitVoid2: () => this.a, // ok, this: any because it refers to some outer object (window?)
|
||||
explicitVoid1() { return 12; },
|
||||
explicitStructural() {
|
||||
return this.a;
|
||||
},
|
||||
explicitInterface() {
|
||||
return this.a;
|
||||
},
|
||||
explicitThis() {
|
||||
return this.a;
|
||||
},
|
||||
implicitMethod() {
|
||||
return this.a;
|
||||
},
|
||||
implicitFunction: () => this.a, // ok, this: any because it refers to some outer object (window?)
|
||||
}
|
||||
impl.explicitVoid1 = function () { return 12; };
|
||||
impl.explicitVoid2 = () => 12;
|
||||
impl.explicitStructural = function() { return this.a; };
|
||||
impl.explicitInterface = function() { return this.a; };
|
||||
impl.explicitStructural = () => 12;
|
||||
impl.explicitInterface = () => 12;
|
||||
impl.explicitThis = function () { return this.a; };
|
||||
impl.implicitMethod = function () { return this.a; };
|
||||
impl.implicitMethod = () => 12;
|
||||
impl.implicitFunction = () => this.a; // ok, this: any because it refers to some outer object (window?)
|
||||
// parameter checking
|
||||
let ok: {y: number, f: (this: { y: number }, x: number) => number} = { y: 12, f: explicitStructural };
|
||||
let implicitAnyOk: {notSpecified: number, f: (x: number) => number} = { notSpecified: 12, f: implicitThis };
|
||||
ok.f(13);
|
||||
implicitThis(12);
|
||||
implicitAnyOk.f(12);
|
||||
|
||||
let c = new C();
|
||||
let d = new D();
|
||||
let ripped = c.explicitC;
|
||||
c.explicitC(12);
|
||||
c.explicitProperty(12);
|
||||
c.explicitThis(12);
|
||||
c.implicitThis(12);
|
||||
d.explicitC(12);
|
||||
d.explicitProperty(12);
|
||||
d.explicitThis(12);
|
||||
d.implicitThis(12);
|
||||
let reconstructed: {
|
||||
n: number,
|
||||
explicitThis(this: C, m: number): number, // note: this: this is not allowed in an object literal type.
|
||||
implicitThis(m: number): number,
|
||||
explicitC(this: C, m: number): number,
|
||||
explicitProperty: (this: {n : number}, m: number) => number,
|
||||
explicitVoid(this: void, m: number): number,
|
||||
} = {
|
||||
n: 12,
|
||||
explicitThis: c.explicitThis,
|
||||
implicitThis: c.implicitThis,
|
||||
explicitC: c.explicitC,
|
||||
explicitProperty: c.explicitProperty,
|
||||
explicitVoid: c.explicitVoid
|
||||
};
|
||||
reconstructed.explicitProperty(11);
|
||||
reconstructed.implicitThis(11);
|
||||
|
||||
// assignment checking
|
||||
let unboundToSpecified: (this: { y: number }, x: number) => number = x => x + this.y; // ok, this:any
|
||||
let specifiedToSpecified: (this: {y: number}, x: number) => number = explicitStructural;
|
||||
let anyToSpecified: (this: { y: number }, x: number) => number = function(x: number): number { return x + 12; };
|
||||
|
||||
let unspecifiedLambda: (x: number) => number = x => x + 12;
|
||||
let specifiedLambda: (this: void, x: number) => number = x => x + 12;
|
||||
let unspecifiedLambdaToSpecified: (this: {y: number}, x: number) => number = unspecifiedLambda;
|
||||
let specifiedLambdaToSpecified: (this: {y: number}, x: number) => number = specifiedLambda;
|
||||
|
||||
|
||||
let explicitCFunction: (this: C, m: number) => number;
|
||||
let explicitPropertyFunction: (this: {n: number}, m: number) => number;
|
||||
c.explicitC = explicitCFunction;
|
||||
c.explicitC = function(this: C, m: number) { return this.n + m };
|
||||
c.explicitProperty = explicitPropertyFunction;
|
||||
c.explicitProperty = function(this: {n: number}, m: number) { return this.n + m };
|
||||
c.explicitProperty = reconstructed.explicitProperty;
|
||||
|
||||
// lambdas are assignable to anything
|
||||
c.explicitC = m => m;
|
||||
c.explicitThis = m => m;
|
||||
c.explicitProperty = m => m;
|
||||
|
||||
// this inside lambdas refer to outer scope
|
||||
// the outer-scoped lambda at top-level is still just `any`
|
||||
c.explicitC = m => m + this.n;
|
||||
c.explicitThis = m => m + this.n;
|
||||
c.explicitProperty = m => m + this.n;
|
||||
|
||||
//NOTE: this=C here, I guess?
|
||||
c.explicitThis = explicitCFunction;
|
||||
c.explicitThis = function(this: C, m: number) { return this.n + m };
|
||||
|
||||
// this:any compatibility
|
||||
c.explicitC = function(m: number) { return this.n + m };
|
||||
c.explicitProperty = function(m: number) { return this.n + m };
|
||||
c.explicitThis = function(m: number) { return this.n + m };
|
||||
c.implicitThis = function(m: number) { return this.n + m };
|
||||
c.implicitThis = reconstructed.implicitThis;
|
||||
|
||||
c.explicitC = function(this: B, m: number) { return this.n + m };
|
||||
|
||||
// this:void compatibility
|
||||
c.explicitVoid = n => n;
|
||||
|
||||
// class-based assignability
|
||||
class Base1 {
|
||||
x: number;
|
||||
public implicit(): number { return this.x; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
static implicitStatic(): number { return this.y; }
|
||||
static explicitStatic(this: typeof Base1): number { return this.y; }
|
||||
static y: number;
|
||||
|
||||
}
|
||||
class Derived1 extends Base1 {
|
||||
y: number
|
||||
}
|
||||
class Base2 {
|
||||
y: number
|
||||
implicit(): number { return this.y; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
}
|
||||
class Derived2 extends Base2 {
|
||||
x: number
|
||||
}
|
||||
let b1 = new Base1();
|
||||
let b2 = new Base2();
|
||||
let d1 = new Derived1();
|
||||
let d2 = new Derived2();
|
||||
d2.implicit = d1.implicit // ok, 'x' and 'y' in { x, y } (d assignable to f and vice versa)
|
||||
d1.implicit = d2.implicit // ok, 'x' and 'y' in { x, y } (f assignable to d and vice versa)
|
||||
|
||||
// bivariance-allowed cases
|
||||
d1.implicit = b2.implicit // ok, 'y' in D: { x, y } (d assignable e)
|
||||
d2.implicit = d1.explicit // ok, 'y' in { x, y } (c assignable to f)
|
||||
b1.implicit = d2.implicit // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
b1.explicit = d2.implicit // ok, 'x' and 'y' not in C: { x } (c assignable to f)
|
||||
|
||||
////// use this-type for construction with new ////
|
||||
function InterfaceThis(this: I) {
|
||||
this.a = 12;
|
||||
}
|
||||
function LiteralTypeThis(this: {x: string}) {
|
||||
this.x = "ok";
|
||||
}
|
||||
function AnyThis(this: any) {
|
||||
this.x = "ok";
|
||||
}
|
||||
let interfaceThis = new InterfaceThis();
|
||||
let literalTypeThis = new LiteralTypeThis();
|
||||
let anyThis = new AnyThis();
|
||||
|
||||
//// type parameter inference ////
|
||||
declare var f: {
|
||||
(this: void, x: number): number,
|
||||
call<U>(this: (...argArray: any[]) => U, ...argArray: any[]): U;
|
||||
};
|
||||
let n: number = f.call(12);
|
||||
|
||||
function missingTypeIsImplicitAny(this, a: number) { return a; }
|
||||
@ -0,0 +1,193 @@
|
||||
// @strictThis: true
|
||||
class C {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
implicitThis(m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitC(this: C, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitProperty(this: {n: number}, m: number): number {
|
||||
return this.n + m;
|
||||
}
|
||||
explicitVoid(this: void, m: number): number {
|
||||
return this.n + m; // 'n' doesn't exist on type 'void'.
|
||||
}
|
||||
}
|
||||
class D {
|
||||
x: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
explicitD(this: D, m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
implicitD(m: number): number {
|
||||
return this.x + m;
|
||||
}
|
||||
}
|
||||
interface I {
|
||||
a: number;
|
||||
explicitVoid1(this: void): number;
|
||||
explicitVoid2(this: void): number;
|
||||
explicitStructural(this: {a: number}): number;
|
||||
explicitInterface(this: I): number;
|
||||
explicitThis(this: this): number; // TODO: Allow `this` types for interfaces
|
||||
implicitMethod(): number;
|
||||
implicitFunction: () => number;
|
||||
}
|
||||
let impl: I = {
|
||||
a: 12,
|
||||
explicitVoid1() {
|
||||
return this.a; // error, no 'a' in 'void'
|
||||
},
|
||||
explicitVoid2: () => this.a, // ok, `this:any` because it refers to an outer object
|
||||
explicitStructural: () => 12,
|
||||
explicitInterface: () => 12,
|
||||
explicitThis() {
|
||||
return this.a;
|
||||
},
|
||||
implicitMethod() {
|
||||
return this.a; // ok, I.a: number
|
||||
},
|
||||
implicitFunction: function () { return this.a; } // TODO: error 'a' not found in 'void'
|
||||
}
|
||||
let implExplicitStructural = impl.explicitStructural;
|
||||
implExplicitStructural(); // error, no 'a' in 'void'
|
||||
let implExplicitInterface = impl.explicitInterface;
|
||||
implExplicitInterface(); // error, no 'a' in 'void'
|
||||
let implImplicitMethod = impl.implicitMethod;
|
||||
implImplicitMethod(); // error, no 'a' in 'void'
|
||||
function explicitStructural(this: { y: number }, x: number): number {
|
||||
return x + this.y;
|
||||
}
|
||||
function propertyName(this: { y: number }, x: number): number {
|
||||
return x + this.notFound;
|
||||
}
|
||||
function voidThisSpecified(this: void, x: number): number {
|
||||
return x + this.notSpecified;
|
||||
}
|
||||
function noThisSpecified(x: number): number {
|
||||
// this:void unless loose-this is on
|
||||
return x + this.notSpecified;
|
||||
}
|
||||
let ok: {y: number, f: (this: { y: number }, x: number) => number} = { y: 12, explicitStructural };
|
||||
let wrongPropertyType: {y: string, f: (this: { y: number }, x: number) => number} = { y: 'foo', explicitStructural };
|
||||
let wrongPropertyName: {wrongName: number, f: (this: { y: number }, x: number) => number} = { wrongName: 12, explicitStructural };
|
||||
|
||||
ok.f(); // not enough arguments
|
||||
ok.f('wrong type');
|
||||
ok.f(13, 'too many arguments');
|
||||
wrongPropertyType.f(13);
|
||||
wrongPropertyName.f(13);
|
||||
|
||||
let c = new C();
|
||||
c.explicitC(); // not enough arguments
|
||||
c.explicitC('wrong type');
|
||||
c.explicitC(13, 'too many arguments');
|
||||
c.explicitThis(); // not enough arguments
|
||||
c.explicitThis('wrong type 2');
|
||||
c.explicitThis(14, 'too many arguments 2');
|
||||
c.implicitThis(); // not enough arguments
|
||||
c.implicitThis('wrong type 2');
|
||||
c.implicitThis(14, 'too many arguments 2');
|
||||
c.explicitProperty(); // not enough arguments
|
||||
c.explicitProperty('wrong type 3');
|
||||
c.explicitProperty(15, 'too many arguments 3');
|
||||
|
||||
// oops, this triggers contextual typing, which needs to be updated to understand that =>'s `this` is void.
|
||||
let specifiedToImplicitVoid: (x: number) => number = explicitStructural;
|
||||
|
||||
let reconstructed: {
|
||||
n: number,
|
||||
explicitThis(this: C, m: number): number, // note: this: this is not allowed in an object literal type.
|
||||
implicitThis(m: number): number,
|
||||
explicitC(this: C, m: number): number,
|
||||
explicitProperty: (this: {n : number}, m: number) => number,
|
||||
explicitVoid(this: void, m: number): number,
|
||||
} = {
|
||||
n: 12,
|
||||
explicitThis: c.explicitThis,
|
||||
implicitThis: c.implicitThis, // error not assignable -- c.this:c<this> not assignable to this:void.
|
||||
explicitC: c.explicitC,
|
||||
explicitProperty: c.explicitProperty,
|
||||
explicitVoid: c.explicitVoid
|
||||
};;
|
||||
|
||||
// lambdas have this: void for assignability purposes (and this unbound (free) for body checking)
|
||||
let d = new D();
|
||||
let explicitXProperty: (this: { x: number }, m: number) => number;
|
||||
|
||||
// from differing object types
|
||||
c.explicitC = function(this: D, m: number) { return this.x + m };
|
||||
c.explicitProperty = explicitXProperty;
|
||||
|
||||
c.explicitC = d.implicitD;
|
||||
c.explicitC = d.explicitD;
|
||||
c.explicitC = d.explicitThis;
|
||||
c.explicitThis = d.implicitD;
|
||||
c.explicitThis = d.explicitD;
|
||||
c.explicitThis = d.explicitThis;
|
||||
c.explicitProperty = d.explicitD;
|
||||
c.explicitProperty = d.implicitD;
|
||||
c.explicitThis = d.explicitThis;
|
||||
c.explicitVoid = d.implicitD;
|
||||
c.explicitVoid = d.explicitD;
|
||||
c.explicitVoid = d.explicitThis;
|
||||
|
||||
/// class-based implicit assignability (with inheritance!) ///
|
||||
|
||||
class Base1 {
|
||||
x: number
|
||||
public implicit(): number { return this.x; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
static implicitStatic(): number { return this.x; }
|
||||
static explicitStatic(this: typeof Base1): number { return this.x; }
|
||||
}
|
||||
class Derived1 extends Base1 {
|
||||
y: number
|
||||
}
|
||||
class Base2 {
|
||||
y: number
|
||||
implicit(): number { return this.y; }
|
||||
explicit(this: Base1): number { return this.x; }
|
||||
}
|
||||
class Derived2 extends Base2 {
|
||||
x: number
|
||||
}
|
||||
|
||||
|
||||
let b1 = new Base1();
|
||||
let d1 = new Derived1();
|
||||
let b2 = new Base2();
|
||||
let d2 = new Derived2();
|
||||
|
||||
b1.implicit = b2.implicit // error, 'this.y' not in C: { x } (c assignable to e)
|
||||
b1.explicit = b2.implicit // error, 'y' not in C: { x } (c assignable to e)
|
||||
|
||||
d1.explicit = b2.implicit // error, 'y' not in C: { x } (c assignable to e)
|
||||
|
||||
////// use this-type for construction with new ////
|
||||
function VoidThis(this: void) {
|
||||
|
||||
}
|
||||
function ImplicitVoidThis() {
|
||||
|
||||
}
|
||||
let voidThis = new VoidThis();
|
||||
let implicitVoidThis = new ImplicitVoidThis();
|
||||
|
||||
|
||||
///// parse errors /////
|
||||
function notFirst(a: number, this: C): number { return this.n; }
|
||||
function modifiers(async this: C): number { return this.n; }
|
||||
function restParam(...this: C): number { return this.n; }
|
||||
function optional(this?: C): number { return this.n; }
|
||||
function decorated(@deco() this: C): number { return this.n; }
|
||||
function initializer(this: C = new C()): number { return this.n; }
|
||||
|
||||
// can't name parameters 'this' in a lambda.
|
||||
c.explicitProperty = (this, m) => m + this.n;
|
||||
30
tests/cases/fourslash/memberListOnExplicitThis.ts
Normal file
30
tests/cases/fourslash/memberListOnExplicitThis.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// @strictThis: true
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////interface Restricted {
|
||||
//// n: number;
|
||||
////}
|
||||
////class C1 implements Restricted {
|
||||
//// n: number;
|
||||
//// m: number;
|
||||
//// f() {this./*1*/} // test on 'this.'
|
||||
//// g(this: Restricted) {this./*2*/}
|
||||
////}
|
||||
////function f() {this./*3*/}
|
||||
////function g(this: Restricted) {this./*4*/}
|
||||
|
||||
goTo.marker('1');
|
||||
verify.memberListContains('f', '(method) C1.f(this: this): void');
|
||||
verify.memberListContains('g', '(method) C1.g(this: Restricted): void');
|
||||
verify.memberListContains('n', '(property) C1.n: number');
|
||||
verify.memberListContains('m', '(property) C1.m: number');
|
||||
|
||||
goTo.marker('2');
|
||||
verify.memberListContains('n', '(property) Restricted.n: number');
|
||||
|
||||
goTo.marker('3');
|
||||
verify.memberListIsEmpty();
|
||||
|
||||
goTo.marker('4');
|
||||
verify.memberListContains('n', '(property) Restricted.n: number');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user