GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Typed 'this' in object literal methods by ahejlsberg · Pull Request #14141 · microsoft/TypeScript

Conversation

@ahejlsberg

@ahejlsberg Anders Hejlsberg (ahejlsberg) commented Feb 17, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

With this PR we strongly type this in methods of object literals and provide a facility for controlling the type of this through contextual typing. The new behavior is only enabled in --noImplicitThis mode.

The type of the expression this in a method of an object literal is now determined as follows:

  • If the method has an explicitly declared this parameter, this has the type of that parameter.
  • Otherwise, if the method is contextually typed by a signature with a this parameter, this has the type of that parameter.
  • Otherwise, if --noImplicitThis is enabled and the containing object literal has a contextual type that includes a ThisType<T>, this has type T.
  • Otherwise, if --noImplicitThis is enabled and the containing object literal has a contextual type that doesn't include a ThisType<T>, this has the contextual type.
  • Otherwise, if --noImplicitThis is enabled this has the type of the containing object literal.
  • Otherwise, this has type any.

Some examples:

// Compile with --noImplicitThis

type Point = {
    x: number;
    y: number;
    moveBy(dx: number, dy: number): void;
}

let p: Point = {
    x: 10,
    y: 20,
    moveBy(dx, dy) {
        this.x += dx;  // this has type Point
        this.y += dy;  // this has type Point
    }
}

let foo = {
    x: "hello",
    f(n: number) {
        this;  // { x: string, f(n: number): void }
    },
}

let bar = {
    x: "hello",
    f(this: { message: string }) {
        this;  // { message: string }
    },
}

In a similar manner, when --noImplicitThis is enabled and a function expression is assigned to a target of the form obj.xxx or obj[xxx], the contextual type for this in the function expression is obj:

// Compile with --noImplicitThis

obj.f = function(n) {
    return this.x - n;  // 'this' has same type as 'obj'
}

obj['f'] = function(n) {
    return this.x - n;  // 'this' has same type as 'obj'
}

In cases where an API produces a this value by transforming its arguments, a new ThisType<T> marker interface can be used to contextually indicate the transformed type. Specifically, when the contextual type for an object literal is ThisType<T> or an intersection including ThisType<T>, the type of this within methods of the object literal is T.

// Compile with --noImplicitThis

type ObjectDescriptor<D, M> = {
    data?: D;
    methods?: M & ThisType<D & M>;  // Type of 'this' in methods is D & M
}

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
    let data: object = desc.data || {};
    let methods: object = desc.methods || {};
    return { ...data, ...methods } as D & M;
}

let obj = makeObject({
    data: { x: 0, y: 0 },
    methods: {
        moveBy(dx: number, dy: number) {
            this.x += dx;  // Strongly typed this
            this.y += dy;  // Strongly typed this
        }
    }
});

obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);

In the example above, the methods object in the argument to makeObject has a contextual type that includes ThisType<D & M> and therefore the type of this in methods within the methods object is { x: number, y: number } & { moveBy(dx: number, dy: number): number }. Notice how the type of the methods property simultaneously is an inference target and a source for the this type in methods.

The ThisType<T> marker interface is simply an empty interface declared in lib.d.ts. Beyond being recognized in the contextual type of an object literal, the interface acts like any empty interface.

Patterns similar to the above are used in several frameworks, including for example Vue and Ember. Using ThisType<T> we can now more accurately describe those frameworks.

Supercedes #8382. We revoked that PR because it always made the type of this in object literal methods be the type of the object literal. We now make that the default behavior, but allow the default to be overridden using a ThisType<T> contextual type.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

gdh1995, HerringtonDarkholme, styfle, jthomaschewski, Igorbek, rchaser53, ulrichb, svieira, mohsen1, mmc41, and 34 more reacted with thumbs up emoji Jessidhia, alexrock, HerringtonDarkholme, Igorbek, svieira, mpawelski, mquandalle, gabomgp, steve8708, danielhe, and 6 more reacted with hooray emoji steve8708, saeedtabrizi, mickdekkers, BANG88, rictic, ShyykoSerhiy, jednano, bigopon, ZoranZilicFTN, FernandoBasso, and 2 more reacted with heart emoji
All reactions
  • 👍 44 reactions
  • 🎉 16 reactions
  • ❤️ 12 reactions
Anders Hejlsberg (ahejlsberg) added 5 commits February 14, 2017 12:04
@ahejlsberg
Use '__this__' property in contextual type to indicate type of 'this'
f6a3a3f
@ahejlsberg
Introduce ThisType<T> marker interface
8cd6c5d
@ahejlsberg
Default contextual 'this' type is containing object literal
2ca6164
@ahejlsberg
Update tests
e512376
@ahejlsberg
Accept new baselines
d7e153d
@msftclas Microsoft Contribution License Agreements (msftclas) added the cla-not-required label Feb 17, 2017
@ahejlsberg Anders Hejlsberg (ahejlsberg) changed the title Typed 'this Typed 'this' in object literal methods Feb 17, 2017
Anders Hejlsberg (ahejlsberg) added 2 commits February 16, 2017 20:15
@ahejlsberg
Merge branch 'master' into contextualThisType
fe32bb7
@ahejlsberg
Accept new baselines
27346b1
This was referenced Feb 17, 2017
Option to make this in functions inside object literals typed #12785
Closed
No referencing/intellisense fo nested properties/functions within class #7801
Closed
this in function declarations inside object literals should be typed #8110
Closed
Incorrect/overly strong this inference for POJOs #8191
Closed
Intellisense support in 'this' keyword inside an object. #9583
Closed
@ahejlsberg
Contextual this in 'obj.xxx = function(...)' or 'obj[xxx] = function(…
e3a0687
…...)'
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Feb 17, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Latest commit adds contextual this type in assignments of the form obj.xxx = function(...) and obj[xxx] = function(...).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Feb 17, 2017

Copy link
Copy Markdown
Member Author

The one issue that remains for discussion here is whether the strongly typed this behavior should always be in effect or only be in effect in --noImplicitThis mode. It is technically a breaking change, but it also provides a better authoring experience (statement completion for this) and catches legitimate bugs.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

sandersn
Nathan Shively-Sanders (sandersn) requested changes Feb 17, 2017
View reviewed changes

@sandersn Nathan Shively-Sanders (sandersn) left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this change.

  1. Still need tests
  2. Braden Snell (@bradenhs) points out that the contextual typing code only applies to functions and object literal methods. It should apply to object literal getters/setters as well.
  3. I ran RWC to see what breaks. I found several good breaks, a few breaks that require a d.ts update with ThisType (Object.defineProperty, knockout and react), and a couple of places that show that this needs to be the intersection of the object literal type and the parameter type.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts Outdated
}

function getThisTypeFromContextualType(type: Type): Type {
return applyToContextualType(type, t => {

@sandersn Nathan Shively-Sanders (sandersn) Feb 17, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't applyToContextualType just be named mapType and replace mapType? It doesn't do anything specific to contextual types that I could see, and it's better than the current mapType because it skips return values of undefined. #Resolved

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@ahejlsberg Anders Hejlsberg (ahejlsberg) Feb 25, 2017

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes sense.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread tests/baselines/reference/fixSignatureCaching.errors.txt Outdated
tests/cases/conformance/fixSignatureCaching.ts(640,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(641,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(704,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(704,45): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'.

@sandersn Nathan Shively-Sanders (sandersn) Feb 17, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of this test isn't obvious without following the pointer back to issue #10697. Can you add one more comment at the top of the file like "this test originally failed by using 100% CPU and should now take less than 1 second to run". I'd like a faster way to know that these additional failures are not a problem.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread tests/baselines/reference/thisTypeInFunctions2.js Outdated
this // this: containing object literal type
this.mine
this.willDestroy
//this.willDestroy

@sandersn Nathan Shively-Sanders (sandersn) Feb 17, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just delete this, I think. #Resolved

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@ahejlsberg Anders Hejlsberg (ahejlsberg) Feb 25, 2017

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ghost ghost mentioned this pull request Feb 17, 2017
HTMLElement onchange should use this: this microsoft/TypeScript-DOM-lib-generator#195
Open
@sandersn

Nathan Shively-Sanders (sandersn) commented Feb 17, 2017

Copy link
Copy Markdown
Member

Summary of RWC breaks [1]: two good breaks from contextual typing of function assignment. Two breaks that show that Object.defineProperty and friends need to include ThisType<T>. One break that shows that choosing the contextual type of the object literal instead of the contextual type from a function call argument is incorrect.

[1] Note that I haven't looked at all of RWC yet; it hit a stack overflow halfway through.

  1. A good break resulting from contextual typing of function assignment.
declare function f(elt: HTMLElement): void;
function outer() {
  var self = this;
  var args: Draggable;
  args.helper = function () {
    return f(this); 
    
      // error 'this: Draggable' is not assignable to 'HTMLElement'
      //   Property 'accessKey' is missing in 'Draggable'
  };
}

This catches code that is just wrong. I looked at Draggable and it's not at all related to HTMLElement.

(This happened in two different projects.)

  1. Another break from contextual typing of function assignment.
// Override the prototype method on C
CBase.prototype.debug = function() {
  var self: C = this;
    // error type 'CBase' is not assignable to 'C'
    //   Property '_subclassProperty' is missing in 'CBase'

I'm not sure what to make of this. The comment makes it sound like the intention is to override the method on C, not on CBase. So probably this is a good error too.

  1. Defining properties on Array.prototype using Object.defineProperties.
Object.defineProperties(Array.prototype, {
  empty: {
    value: function() {
      return this.length === 0;
    }
  }
})

It looks like Object.defineProperties and related methods need to use ThisType to provide the correct type for this here.

  1. Implicit any errors on a this type that has no index signature.
function defineProperty(c: any, name: string, defaultValue: any) {
  var backingFieldName = "_" + name;
  Object.defineProperty(
    c.prototype,
    name,
    {
      get: function(): any {
        if (typeof this[backingFieldName] === 'undefined') {
          this[backingFieldName] = defaultValue;
        }
        return this[backingFieldName];
      }, // code continues ...
    }); 
};

This would also be fixed by adding ThisType to Object.defineProperty because c.prototype: any and would avoid the noImplicitAny error.

  1. Object literal type overrides contextual type:
interface MockJaxOptions {
  url?: string;
  responseTime?: number;
  status?: number;
  responseText?: string;
  responseHeaders: StringMap<string>;
}

$.mockjax({
  type: "GET",
  url: "blah/blah/blah",
  status: 200,
  contentType: "application/json",
  response: function() {
    this.responseText = JSON.stringify({ stuff: "things" });
    // error: property 'responseText' does not exist on '{ type: string ... }'
  }
});

This is bad because $.mockjax shouldn't really need to have its parameter be of type MockJaxOptions & ThisType<MockJaxOptions>.
I have a hunch this is fairly old code because JQuery MockJax now has its own d.ts. So we could fix this particular break in only one place, but it is symptomatic of a larger problem.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@sandersn

Nathan Shively-Sanders (sandersn) commented Feb 17, 2017

Copy link
Copy Markdown
Member

More breaks:

  1. In vscode/src/vs/languages/markdown/common/markdownWorker.ts:
    	public getEmitOutput(resource: URI, absoluteWorkersResourcePath: string): WinJS.TPromise<Modes.IEmitOutput> { // TODO@Ben technical debt: worker cannot resolve paths absolute
    		let model = this.resourceService.get(resource);
    		let cssLinks: string[] = this.cssLinks || [];
    
    		// Custom Renderer to fix href in images
    		let renderer = new Marked.marked.Renderer();
    		let $this = this;
    		renderer.image = function(href: string, title: string, text: string): string {
    			let out = '<img src="' + $this.fixHref(resource, href) + '" alt="' + text + '"';
    			if (title) {
    				out += ' title="' + title + '"';
    			}
    
    			out += (this.options && this.options.xhtml) ? '/>' : '>';
    			             ~~~~~~~
!!! error TS2339: Property 'options' does not exist on type 'MarkedRenderer'.
    			                             ~~~~~~~
!!! error TS2339: Property 'options' does not exist on type 'MarkedRenderer'.

This seems like a good break. I can't find a property named 'options' in MarkedRenderer or in the class that contains getEmitOutput.

  1. Knockout's observable.fn entries don't specify that this is callable.
ko.observable.fn['toInt'] = function() {
  return parseInt(this());
                  ~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'KnockoutObservableFunctions<any>' has no compatible call signatures.
}

This seems like an easy fix to knockout's d.ts. It's just that nobody ever noticed that KnockoutBindingHandler needed to have a line (): any at the beginning.

  1. RxJs/src/observable/dom/AjaxObservable.ts gets contextual typing from assignment
      private setupEvents(xhr: XMLHttpRequest, request: AjaxRequest) {
        const progressSubscriber = request.progressSubscriber;
    
        xhr.ontimeout = function xhrTimeout(e) {
          const {subscriber, progressSubscriber, request } = (<any>xhrTimeout);
          if (progressSubscriber) {
            progressSubscriber.error(e);
          }
          subscriber.error(new AjaxTimeoutError(this, request)); //TODO: Make betterer.
                                                ~~~~
!!! error TS2345: Argument of type 'XMLHttpRequestEventTarget' is not assignable to parameter of type 'XMLHttpRequest'.
!!! error TS2345:   Property 'onreadystatechange' is missing in type 'XMLHttpRequestEventTarget'.
        };

This seems like a good break too. The comment even indicates that the author is suspicious that something is wrong.

  1. Angular 2 decorators_spec.ts
export function main() {
      describe('es5 decorators', () => {
        it('should declare directive class', () => {
          var MyDirective = Directive({}).Class({constructor: function() { this.works = true; }});
                                                                                ~~~~~
!!! error TS2339: Property 'works' does not exist on type '{ constructor: () => void; }'.
          expect(new MyDirective().works).toEqual(true);
        });

This is probably another case where the type of the object literal needs to be intersected with the contextual type from the call signature. But it's in a test. It could just be a completely dynamic use of an undeclared property.

  1. Angular 2 React benchmark
    // tree benchmark in React
    import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
    import * as React from './react.min';
    
    var TreeComponent = React.createClass({
      displayName: 'TreeComponent',
    
      render: function() {
        var treeNode = this.props.treeNode;
                            ~~~~~
!!! error TS2339: Property 'props' does not exist on type '{ displayName: string; render: () => any; }'.

This is evidence that React.createClass will need to update its d.ts too.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bradenhs Braden Snell (bradenhs) mentioned this pull request Feb 21, 2017
Typescript Examples mobxjs/mobx-state-tree#9
Closed
@bradenhs

Braden Snell (bradenhs) commented Feb 21, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

I just tried this out and thought this would work:

const person = {
  firstName: 'First',
  lastName: 'Last',
  getName() {
    // works!
    return this.firstName + ' ' + this.lastName;
  },
  get name() {
    // 'this' implicitly has type 'any' because it does not have a type annotation.
    return this.firstName + ' ' + this.lastName;
  },
};

But it looks like the getter isn't aware of the type of this. Is this behavior correct?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@sandersn

Nathan Shively-Sanders (sandersn) commented Feb 21, 2017

Copy link
Copy Markdown
Member

Braden Snell (@bradenhs) Nope, that is not correct. But the code right now specifically works with the contextual type of this in functions and methods. It needs code to support getters and setters too. I'll update my review comment above so Anders Hejlsberg (@ahejlsberg) will see it when he gets back from vacaation.

bradenhs, Jessidhia, and HerringtonDarkholme reacted with thumbs up emoji
All reactions
  • 👍 3 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Anders Hejlsberg (ahejlsberg) added 4 commits February 22, 2017 19:16
@ahejlsberg
Contextually type 'this' in accessors of object literals
168d367
@ahejlsberg
Accept new baselines
c2d8a59
@ahejlsberg
Update test
ec292c9
@ahejlsberg
Fix linting error
9b6b6cc
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Feb 23, 2017

Copy link
Copy Markdown
Member Author

With latest commits we now properly type this in getters and setters.

bradenhs and anurbol reacted with thumbs up emoji svieira reacted with hooray emoji
All reactions
  • 👍 2 reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

sandersn
Nathan Shively-Sanders (sandersn) reviewed Feb 23, 2017
View reviewed changes
Comment thread tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt
@@ -22,9 +21,6 @@ tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(16,22): er
}
const contextual: Foo = {

@sandersn Nathan Shively-Sanders (sandersn) Feb 23, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this test case to thisTypeInAccessors.ts so that we can see the types?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Mar 2, 2017

Copy link
Copy Markdown
Member Author

Latest commit puts all of the new functionality under the --noImplicitThis switch. This ensures there are no breaking changes as a result of this PR since the situations in which we strongly type this in object literal methods were previously errors under --noImplicitThis.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg Anders Hejlsberg (ahejlsberg) added this to the TypeScript 2.3 milestone Mar 2, 2017
@aozgaa

Arthur Ozga (aozgaa) commented Mar 2, 2017

Copy link
Copy Markdown
Contributor

In the SymbolDisplayBuilder, should we change the following?

                    else if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) {
                        if (inObjectTypeLiteral) {
                            writer.reportInaccessibleThisError();
                        }
                        writer.writeKeyword("this");
                    }
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Anders Hejlsberg (ahejlsberg) added 2 commits March 1, 2017 17:16
@ahejlsberg
Add ThisType<any> to Object.{create|defineProperty|defineProperties}
7561cdf
@ahejlsberg
Accept new baselines
258bb4f
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Mar 2, 2017

Copy link
Copy Markdown
Member Author

Arthur Ozga (@aozgaa) No, that is an unrelated check (it reports an error if this is accessed in a type position within an object type literal).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Mar 2, 2017

Copy link
Copy Markdown
Member Author

Mohamed Hegazy (@mhegazy) I think this one is good to do. Want to take a look?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Mar 3, 2017
Feature request: parseComponent's pad: true option should use spaces for padding vuejs/vue#5058
Closed
CompletionProvider / IntelliSense vuejs/vetur#26
Closed
mhegazy
Mohamed Hegazy (mhegazy) approved these changes Mar 6, 2017
View reviewed changes
@ahejlsberg
Anders Hejlsberg (ahejlsberg) merged commit 41226d0 into master Mar 6, 2017
@ahejlsberg
Anders Hejlsberg (ahejlsberg) deleted the contextualThisType branch March 6, 2017 21:11
@gdh1995 Dahan Gong (gdh1995) mentioned this pull request Mar 7, 2017
ThisType may be null unexpectly if strictNullChecks is enabled #14504
Closed
@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) mentioned this pull request Mar 7, 2017
Users shouldn't need 'noImplicitThis' on to benefit from 'ThisType<T>' #14518
Closed
@kitsonk Kitson Kelly (kitsonk) mentioned this pull request Mar 9, 2017
Migration to TypeScript 2.3 dojo/meta#153
Closed
@octref Pine (octref) mentioned this pull request Mar 17, 2017
Add vue.d.ts and typescript support vuejs/vetur#94
Merged
This was referenced Apr 12, 2017
Question: Why does "this" not have a type in function assigned to class prototype #8024
Closed
Object literals use contextual type for this when available and ignore type of literal itself. #15157
Closed
@mhegazy Mohamed Hegazy (mhegazy) mentioned this pull request Apr 17, 2017
Go to definition cannot work as expected #15218
Closed
@mattiamanzati Mattia Manzati (mattiamanzati) mentioned this pull request Apr 26, 2017
introduce utility methods? mobxjs/mobx-state-tree#84
Closed
@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) mentioned this pull request May 15, 2017
[Feature Request] A way to instruct how to infer this #15836
Closed
@bryanbecker Bryan (bryanbecker) mentioned this pull request May 17, 2017
Tasks cleanup screepers/screeps-typescript-starter#44
Closed
@mjbvz Matt Bierner (mjbvz) mentioned this pull request Jun 1, 2017
Typed this in JavaScript Object Literals #16184
Closed
@dwickern

Derek Wickern (dwickern) commented Jun 13, 2017

Copy link
Copy Markdown

In this scenario, is it possible to infer this from the containing object literal? Or declare somehow that wrap does not change the context?

let foo = {
    hello: "hello",
    f() {
        return this.hello; // works
    },
    get p() {
        return this.hello; // works
    },
    g: wrap(function () {
        return this.hello; // TS2683:'this' implicitly has type 'any' because it does not have a type annotation.
    })
}
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Jessidhia

Jessica Franco (Jessidhia) commented Jun 13, 2017

Copy link
Copy Markdown

I haven’t tested it but it should be possible with generics.

declare function wrap<T, F extends (this: T) => any>(f: F): F
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@dwickern

Derek Wickern (dwickern) commented Jun 13, 2017

Copy link
Copy Markdown

Unfortunately that doesn't seem to work without specifying wrap<{ hello: string }>(function() { ... }).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@HerringtonDarkholme Herrington Darkholme (HerringtonDarkholme) mentioned this pull request Aug 17, 2017
Further improve Vue type declarations for canonical usage vuejs/vue#6391
Merged
@mattmccutchen Matt McCutchen (mattmccutchen) mentioned this pull request Sep 21, 2017
Document ThisType<T> microsoft/TypeScript-Handbook#649
Closed
@tomcon Tom Conlon (tomcon) mentioned this pull request Nov 28, 2017
Leverage types for perf improvements sveltejs/svelte#418
Closed
@microsoft Microsoft (microsoft) locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@sandersn Nathan Shively-Sanders (sandersn) sandersn approved these changes
+1 more reviewer
@mhegazy Mohamed Hegazy (mhegazy) mhegazy approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

TypeScript 2.3

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

8 participants

@ahejlsberg @sandersn @bradenhs @aozgaa @dwickern @Jessidhia @mhegazy @msftclas
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.