Merge pull request #9746 from Microsoft/instantiate-this-for-contextually-typed-type-parameters

Instantiate this for contextually typed type parameters
This commit is contained in:
Nathan Shively-Sanders 2016-08-22 16:47:13 -07:00 committed by GitHub
commit f028fa3f52
9 changed files with 201 additions and 58 deletions

View file

@ -3066,9 +3066,14 @@ namespace ts {
}
}
// Use contextual parameter type if one is available
const type = declaration.symbol.name === "this"
? getContextuallyTypedThisType(func)
: getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
let type: Type;
if (declaration.symbol.name === "this") {
const thisParameter = getContextualThisParameter(func);
type = thisParameter ? getTypeOfSymbol(thisParameter) : undefined;
}
else {
type = getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
}
if (type) {
return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
}
@ -4675,6 +4680,9 @@ namespace ts {
if (isJSConstructSignature) {
minArgumentCount--;
}
if (!thisParameter && isObjectLiteralMethod(declaration)) {
thisParameter = getContextualThisParameter(declaration);
}
const classType = declaration.kind === SyntaxKind.Constructor ?
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
@ -9110,10 +9118,6 @@ namespace ts {
return getInferredClassType(classSymbol);
}
}
const type = getContextuallyTypedThisType(container);
if (type) {
return type;
}
const thisType = getThisTypeOfDeclaration(container);
if (thisType) {
@ -9354,11 +9358,11 @@ namespace ts {
}
}
function getContextuallyTypedThisType(func: FunctionLikeDeclaration): Type {
function getContextualThisParameter(func: FunctionLikeDeclaration): Symbol {
if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
const contextualSignature = getContextualSignature(func);
if (contextualSignature) {
return getThisTypeOfSignature(contextualSignature);
return contextualSignature.thisParameter;
}
}
@ -12301,6 +12305,12 @@ namespace ts {
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) {
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
if (context.thisParameter) {
if (!signature.thisParameter) {
signature.thisParameter = createTransientSymbol(context.thisParameter, undefined);
}
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper);
}
for (let i = 0; i < len; i++) {
const parameter = signature.parameters[i];
const contextualParameterType = getTypeAtPosition(context, i);

View file

@ -0,0 +1,20 @@
//// [instantiateContextuallyTypedGenericThis.ts]
interface JQuery {
each<T>(
collection: T[], callback: (this: T, dit: T) => T
): T[];
}
let $: JQuery;
let lines: string[];
$.each(lines, function(dit) {
return dit.charAt(0) + this.charAt(1);
});
//// [instantiateContextuallyTypedGenericThis.js]
var $;
var lines;
$.each(lines, function (dit) {
return dit.charAt(0) + this.charAt(1);
});

View file

@ -0,0 +1,46 @@
=== tests/cases/compiler/instantiateContextuallyTypedGenericThis.ts ===
interface JQuery {
>JQuery : Symbol(JQuery, Decl(instantiateContextuallyTypedGenericThis.ts, 0, 0))
each<T>(
>each : Symbol(JQuery.each, Decl(instantiateContextuallyTypedGenericThis.ts, 0, 18))
>T : Symbol(T, Decl(instantiateContextuallyTypedGenericThis.ts, 1, 9))
collection: T[], callback: (this: T, dit: T) => T
>collection : Symbol(collection, Decl(instantiateContextuallyTypedGenericThis.ts, 1, 12))
>T : Symbol(T, Decl(instantiateContextuallyTypedGenericThis.ts, 1, 9))
>callback : Symbol(callback, Decl(instantiateContextuallyTypedGenericThis.ts, 2, 24))
>this : Symbol(this, Decl(instantiateContextuallyTypedGenericThis.ts, 2, 36))
>T : Symbol(T, Decl(instantiateContextuallyTypedGenericThis.ts, 1, 9))
>dit : Symbol(dit, Decl(instantiateContextuallyTypedGenericThis.ts, 2, 44))
>T : Symbol(T, Decl(instantiateContextuallyTypedGenericThis.ts, 1, 9))
>T : Symbol(T, Decl(instantiateContextuallyTypedGenericThis.ts, 1, 9))
): T[];
>T : Symbol(T, Decl(instantiateContextuallyTypedGenericThis.ts, 1, 9))
}
let $: JQuery;
>$ : Symbol($, Decl(instantiateContextuallyTypedGenericThis.ts, 6, 3))
>JQuery : Symbol(JQuery, Decl(instantiateContextuallyTypedGenericThis.ts, 0, 0))
let lines: string[];
>lines : Symbol(lines, Decl(instantiateContextuallyTypedGenericThis.ts, 7, 3))
$.each(lines, function(dit) {
>$.each : Symbol(JQuery.each, Decl(instantiateContextuallyTypedGenericThis.ts, 0, 18))
>$ : Symbol($, Decl(instantiateContextuallyTypedGenericThis.ts, 6, 3))
>each : Symbol(JQuery.each, Decl(instantiateContextuallyTypedGenericThis.ts, 0, 18))
>lines : Symbol(lines, Decl(instantiateContextuallyTypedGenericThis.ts, 7, 3))
>dit : Symbol(dit, Decl(instantiateContextuallyTypedGenericThis.ts, 8, 23))
return dit.charAt(0) + this.charAt(1);
>dit.charAt : Symbol(String.charAt, Decl(lib.d.ts, --, --))
>dit : Symbol(dit, Decl(instantiateContextuallyTypedGenericThis.ts, 8, 23))
>charAt : Symbol(String.charAt, Decl(lib.d.ts, --, --))
>this.charAt : Symbol(String.charAt, Decl(lib.d.ts, --, --))
>this : Symbol(this, Decl(instantiateContextuallyTypedGenericThis.ts, 2, 36))
>charAt : Symbol(String.charAt, Decl(lib.d.ts, --, --))
});

View file

@ -0,0 +1,53 @@
=== tests/cases/compiler/instantiateContextuallyTypedGenericThis.ts ===
interface JQuery {
>JQuery : JQuery
each<T>(
>each : <T>(collection: T[], callback: (this: T, dit: T) => T) => T[]
>T : T
collection: T[], callback: (this: T, dit: T) => T
>collection : T[]
>T : T
>callback : (this: T, dit: T) => T
>this : T
>T : T
>dit : T
>T : T
>T : T
): T[];
>T : T
}
let $: JQuery;
>$ : JQuery
>JQuery : JQuery
let lines: string[];
>lines : string[]
$.each(lines, function(dit) {
>$.each(lines, function(dit) { return dit.charAt(0) + this.charAt(1);}) : string[]
>$.each : <T>(collection: T[], callback: (this: T, dit: T) => T) => T[]
>$ : JQuery
>each : <T>(collection: T[], callback: (this: T, dit: T) => T) => T[]
>lines : string[]
>function(dit) { return dit.charAt(0) + this.charAt(1);} : (this: string, dit: string) => string
>dit : string
return dit.charAt(0) + this.charAt(1);
>dit.charAt(0) + this.charAt(1) : string
>dit.charAt(0) : string
>dit.charAt : (pos: number) => string
>dit : string
>charAt : (pos: number) => string
>0 : number
>this.charAt(1) : string
>this.charAt : (pos: number) => string
>this : string
>charAt : (pos: number) => string
>1 : number
});

View file

@ -135,7 +135,7 @@ let impl: I = {
return this.a;
>this.a : Symbol(a, Decl(thisTypeInFunctions.ts, 24, 30))
>this : Symbol(, Decl(thisTypeInFunctions.ts, 24, 28))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 24, 23))
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 24, 30))
},
@ -144,7 +144,7 @@ let impl: I = {
return this.a;
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 19, 21))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 25, 22))
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
},
@ -153,7 +153,7 @@ let impl: I = {
return this.a;
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 19, 21))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 26, 17))
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
},
@ -173,7 +173,7 @@ impl.explicitStructural = function() { return this.a; };
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 37, 3))
>explicitStructural : Symbol(I.explicitStructural, Decl(thisTypeInFunctions.ts, 23, 38))
>this.a : Symbol(a, Decl(thisTypeInFunctions.ts, 24, 30))
>this : Symbol(, Decl(thisTypeInFunctions.ts, 24, 28))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 24, 23))
>a : Symbol(a, Decl(thisTypeInFunctions.ts, 24, 30))
impl.explicitInterface = function() { return this.a; };
@ -181,7 +181,7 @@ impl.explicitInterface = function() { return this.a; };
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 37, 3))
>explicitInterface : Symbol(I.explicitInterface, Decl(thisTypeInFunctions.ts, 24, 50))
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 19, 21))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 25, 22))
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
impl.explicitStructural = () => 12;
@ -199,7 +199,7 @@ impl.explicitThis = function () { return this.a; };
>impl : Symbol(impl, Decl(thisTypeInFunctions.ts, 37, 3))
>explicitThis : Symbol(I.explicitThis, Decl(thisTypeInFunctions.ts, 25, 39))
>this.a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
>this : Symbol(I, Decl(thisTypeInFunctions.ts, 19, 21))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 26, 17))
>a : Symbol(I.a, Decl(thisTypeInFunctions.ts, 20, 13))
// parameter checking
@ -536,7 +536,7 @@ c.explicitC = function(m) { return this.n + m };
>explicitC : Symbol(C.explicitC, Decl(thisTypeInFunctions.ts, 8, 5))
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 126, 23))
>this.n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 4, 9))
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 3, 1))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 9, 14))
>n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 4, 9))
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 126, 23))
@ -546,7 +546,7 @@ c.explicitProperty = function(m) { return this.n + m };
>explicitProperty : Symbol(C.explicitProperty, Decl(thisTypeInFunctions.ts, 11, 5))
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 127, 30))
>this.n : Symbol(n, Decl(thisTypeInFunctions.ts, 12, 28))
>this : Symbol(, Decl(thisTypeInFunctions.ts, 12, 26))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 12, 21))
>n : Symbol(n, Decl(thisTypeInFunctions.ts, 12, 28))
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 127, 30))
@ -556,7 +556,7 @@ c.explicitThis = function(m) { return this.n + m };
>explicitThis : Symbol(C.explicitThis, Decl(thisTypeInFunctions.ts, 5, 14))
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 128, 26))
>this.n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 4, 9))
>this : Symbol(C, Decl(thisTypeInFunctions.ts, 3, 1))
>this : Symbol(this, Decl(thisTypeInFunctions.ts, 6, 17))
>n : Symbol(C.n, Decl(thisTypeInFunctions.ts, 4, 9))
>m : Symbol(m, Decl(thisTypeInFunctions.ts, 128, 26))

View file

@ -132,7 +132,7 @@ function implicitThis(n: number): number {
let impl: I = {
>impl : I
>I : 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; },} : { a: number; explicitVoid2: () => any; explicitVoid1(): number; explicitStructural(): number; explicitInterface(): number; explicitThis(): number; }
>{ 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; },} : { a: number; explicitVoid2: () => any; explicitVoid1(this: void): number; explicitStructural(this: { a: number; }): number; explicitInterface(this: I): number; explicitThis(this: I): number; }
a: 12,
>a : number
@ -146,11 +146,11 @@ let impl: I = {
>a : any
explicitVoid1() { return 12; },
>explicitVoid1 : () => number
>explicitVoid1 : (this: void) => number
>12 : number
explicitStructural() {
>explicitStructural : () => number
>explicitStructural : (this: { a: number; }) => number
return this.a;
>this.a : number
@ -159,7 +159,7 @@ let impl: I = {
},
explicitInterface() {
>explicitInterface : () => number
>explicitInterface : (this: I) => number
return this.a;
>this.a : number
@ -168,7 +168,7 @@ let impl: I = {
},
explicitThis() {
>explicitThis : () => number
>explicitThis : (this: I) => number
return this.a;
>this.a : number
@ -178,11 +178,11 @@ let impl: I = {
},
}
impl.explicitVoid1 = function () { return 12; };
>impl.explicitVoid1 = function () { return 12; } : () => number
>impl.explicitVoid1 = function () { return 12; } : (this: void) => number
>impl.explicitVoid1 : (this: void) => number
>impl : I
>explicitVoid1 : (this: void) => number
>function () { return 12; } : () => number
>function () { return 12; } : (this: void) => number
>12 : number
impl.explicitVoid2 = () => 12;
@ -194,21 +194,21 @@ impl.explicitVoid2 = () => 12;
>12 : number
impl.explicitStructural = function() { return this.a; };
>impl.explicitStructural = function() { return this.a; } : () => number
>impl.explicitStructural = function() { return this.a; } : (this: { a: number; }) => number
>impl.explicitStructural : (this: { a: number; }) => number
>impl : I
>explicitStructural : (this: { a: number; }) => number
>function() { return this.a; } : () => number
>function() { return this.a; } : (this: { a: number; }) => number
>this.a : number
>this : { a: number; }
>a : number
impl.explicitInterface = function() { return this.a; };
>impl.explicitInterface = function() { return this.a; } : () => number
>impl.explicitInterface = function() { return this.a; } : (this: I) => number
>impl.explicitInterface : (this: I) => number
>impl : I
>explicitInterface : (this: I) => number
>function() { return this.a; } : () => number
>function() { return this.a; } : (this: I) => number
>this.a : number
>this : I
>a : number
@ -230,11 +230,11 @@ impl.explicitInterface = () => 12;
>12 : number
impl.explicitThis = function () { return this.a; };
>impl.explicitThis = function () { return this.a; } : () => number
>impl.explicitThis = function () { return this.a; } : (this: I) => number
>impl.explicitThis : (this: I) => number
>impl : I
>explicitThis : (this: I) => number
>function () { return this.a; } : () => number
>function () { return this.a; } : (this: I) => number
>this.a : number
>this : I
>a : number
@ -433,7 +433,7 @@ let unboundToSpecified: (this: { y: number }, x: number) => number = x => x + th
>this : { y: number; }
>y : number
>x : number
>x => x + this.y : (x: number) => any
>x => x + this.y : (this: { y: number; }, x: number) => any
>x : number
>x + this.y : any
>x : number
@ -472,7 +472,7 @@ let specifiedLambda: (this: void, x: number) => number = x => x + 12;
>specifiedLambda : (this: void, x: number) => number
>this : void
>x : number
>x => x + 12 : (x: number) => number
>x => x + 12 : (this: void, x: number) => number
>x : number
>x + 12 : number
>x : number
@ -560,40 +560,40 @@ c.explicitProperty = reconstructed.explicitProperty;
// lambdas are assignable to anything
c.explicitC = m => m;
>c.explicitC = m => m : (m: number) => number
>c.explicitC = m => m : (this: C, m: number) => number
>c.explicitC : (this: C, m: number) => number
>c : C
>explicitC : (this: C, m: number) => number
>m => m : (m: number) => number
>m => m : (this: C, m: number) => number
>m : number
>m : number
c.explicitThis = m => m;
>c.explicitThis = m => m : (m: number) => number
>c.explicitThis = m => m : (this: C, m: number) => number
>c.explicitThis : (this: C, m: number) => number
>c : C
>explicitThis : (this: C, m: number) => number
>m => m : (m: number) => number
>m => m : (this: C, m: number) => number
>m : number
>m : number
c.explicitProperty = m => m;
>c.explicitProperty = m => m : (m: number) => number
>c.explicitProperty = m => m : (this: { n: number; }, m: number) => number
>c.explicitProperty : (this: { n: number; }, m: number) => number
>c : C
>explicitProperty : (this: { n: number; }, m: number) => number
>m => m : (m: number) => number
>m => m : (this: { n: number; }, m: number) => number
>m : number
>m : number
// 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 = m => m + this.n : (m: number) => any
>c.explicitC = m => m + this.n : (this: C, m: number) => any
>c.explicitC : (this: C, m: number) => number
>c : C
>explicitC : (this: C, m: number) => number
>m => m + this.n : (m: number) => any
>m => m + this.n : (this: C, m: number) => any
>m : number
>m + this.n : any
>m : number
@ -602,11 +602,11 @@ c.explicitC = m => m + this.n;
>n : any
c.explicitThis = m => m + this.n;
>c.explicitThis = m => m + this.n : (m: number) => any
>c.explicitThis = m => m + this.n : (this: C, m: number) => any
>c.explicitThis : (this: C, m: number) => number
>c : C
>explicitThis : (this: C, m: number) => number
>m => m + this.n : (m: number) => any
>m => m + this.n : (this: C, m: number) => any
>m : number
>m + this.n : any
>m : number
@ -615,11 +615,11 @@ c.explicitThis = m => m + this.n;
>n : any
c.explicitProperty = m => m + this.n;
>c.explicitProperty = m => m + this.n : (m: number) => any
>c.explicitProperty = m => m + this.n : (this: { n: number; }, m: number) => any
>c.explicitProperty : (this: { n: number; }, m: number) => number
>c : C
>explicitProperty : (this: { n: number; }, m: number) => number
>m => m + this.n : (m: number) => any
>m => m + this.n : (this: { n: number; }, m: number) => any
>m : number
>m + this.n : any
>m : number
@ -652,11 +652,11 @@ c.explicitThis = function(this: C, m: number) { return this.n + m };
// this:any compatibility
c.explicitC = function(m) { return this.n + m };
>c.explicitC = function(m) { return this.n + m } : (m: number) => number
>c.explicitC = function(m) { return this.n + m } : (this: C, m: number) => number
>c.explicitC : (this: C, m: number) => number
>c : C
>explicitC : (this: C, m: number) => number
>function(m) { return this.n + m } : (m: number) => number
>function(m) { return this.n + m } : (this: C, m: number) => number
>m : number
>this.n + m : number
>this.n : number
@ -665,11 +665,11 @@ c.explicitC = function(m) { return this.n + m };
>m : number
c.explicitProperty = function(m) { return this.n + m };
>c.explicitProperty = function(m) { return this.n + m } : (m: number) => number
>c.explicitProperty = function(m) { return this.n + m } : (this: { n: number; }, m: number) => number
>c.explicitProperty : (this: { n: number; }, m: number) => number
>c : C
>explicitProperty : (this: { n: number; }, m: number) => number
>function(m) { return this.n + m } : (m: number) => number
>function(m) { return this.n + m } : (this: { n: number; }, m: number) => number
>m : number
>this.n + m : number
>this.n : number
@ -678,11 +678,11 @@ c.explicitProperty = function(m) { return this.n + m };
>m : number
c.explicitThis = function(m) { return this.n + m };
>c.explicitThis = function(m) { return this.n + m } : (m: number) => number
>c.explicitThis = function(m) { return this.n + m } : (this: C, m: number) => number
>c.explicitThis : (this: C, m: number) => number
>c : C
>explicitThis : (this: C, m: number) => number
>function(m) { return this.n + m } : (m: number) => number
>function(m) { return this.n + m } : (this: C, m: number) => number
>m : number
>this.n + m : number
>this.n : number
@ -723,11 +723,11 @@ c.explicitC = function(this: B, m: number) { return this.n + m };
// this:void compatibility
c.explicitVoid = n => n;
>c.explicitVoid = n => n : (n: number) => number
>c.explicitVoid = n => n : (this: void, n: number) => number
>c.explicitVoid : (this: void, m: number) => number
>c : C
>explicitVoid : (this: void, m: number) => number
>n => n : (n: number) => number
>n => n : (this: void, n: number) => number
>n : number
>n : number

View file

@ -61,12 +61,12 @@ extend1({
>init : Symbol(init, Decl(thisTypeInFunctions2.ts, 20, 9))
this // this: IndexedWithThis because of contextual typing.
>this : Symbol(IndexedWithThis, Decl(thisTypeInFunctions2.ts, 0, 0))
>this : Symbol(this, Decl(thisTypeInFunctions2.ts, 2, 12))
// this.mine
this.willDestroy
>this.willDestroy : Symbol(IndexedWithThis.willDestroy, Decl(thisTypeInFunctions2.ts, 2, 32))
>this : Symbol(IndexedWithThis, Decl(thisTypeInFunctions2.ts, 0, 0))
>this : Symbol(this, Decl(thisTypeInFunctions2.ts, 2, 12))
>willDestroy : Symbol(IndexedWithThis.willDestroy, Decl(thisTypeInFunctions2.ts, 2, 32))
},
@ -77,7 +77,10 @@ extend1({
>foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 26, 13))
this.url; // this: any because 'foo' matches the string indexer
>this : Symbol(this, Decl(thisTypeInFunctions2.ts, 4, 87))
this.willDestroy;
>this : Symbol(this, Decl(thisTypeInFunctions2.ts, 4, 87))
}
});
extend2({

View file

@ -58,10 +58,10 @@ declare function simple(arg: SimpleInterface): void;
extend1({
>extend1({ init() { this // this: IndexedWithThis because of contextual typing. // this.mine this.willDestroy }, mine: 12, foo() { this.url; // this: any because 'foo' matches the string indexer this.willDestroy; }}) : void
>extend1 : (args: IndexedWithThis) => void
>{ init() { this // this: IndexedWithThis because of contextual typing. // this.mine this.willDestroy }, mine: 12, foo() { this.url; // this: any because 'foo' matches the string indexer this.willDestroy; }} : { init(): void; mine: number; foo(): void; }
>{ init() { this // this: IndexedWithThis because of contextual typing. // this.mine this.willDestroy }, mine: 12, foo() { this.url; // this: any because 'foo' matches the string indexer this.willDestroy; }} : { init(this: IndexedWithThis): void; mine: number; foo(this: any): void; }
init() {
>init : () => void
>init : (this: IndexedWithThis) => void
this // this: IndexedWithThis because of contextual typing.
>this : IndexedWithThis
@ -78,7 +78,7 @@ extend1({
>12 : number
foo() {
>foo : () => void
>foo : (this: any) => void
this.url; // this: any because 'foo' matches the string indexer
>this.url : any

View file

@ -0,0 +1,11 @@
interface JQuery {
each<T>(
collection: T[], callback: (this: T, dit: T) => T
): T[];
}
let $: JQuery;
let lines: string[];
$.each(lines, function(dit) {
return dit.charAt(0) + this.charAt(1);
});