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 — Question: Why does "this" not have a type in function assigned to class prototype · Issue #8024 · microsoft/TypeScript

Question: Why does "this" not have a type in function assigned to class prototype  #8024

New issue
Copy link
New issue
Copy link
Closed
Closed
Question: Why does "this" not have a type in function assigned to class prototype #8024
Copy link
Assignees
sandersn
Labels
CommittedThe team has roadmapped this issueThe team has roadmapped this issueFixedA PR has been merged for this issueA PR has been merged for this issue
Milestone
TypeScript 2.4

Description

@ToddThomson
Todd Thomson (ToddThomson)
opened on Apr 12, 2016
Issue body actions

TypeScript Version:

1.8.9

Code

export class Configuration {
    private storage: string;

    constructor() {
        this.storage = "InMemoryStorageProvider()";
    }

    public useLocalStorage(): void {
        // This method will be injected via the prototype.
    }    
}
import { Configuration } from './classes/Configuration';

Configuration.prototype.useLocalStorage = function() {
    this.storage = "NodeFileStorageProvider"
};

Expected behavior:

When walking the AST I use:

let identifier: ts.Identifier = <ts.Identifier>node;
let identifierSymbol: ts.Symbol = this.checker.getSymbolAtLocation( identifier );

to obtain the identifier and its possible associated symbol when the node is SyntaxKind.Identifier.

for the first 2 references to the private property storage, I obtain the identifier and the symbol (which correctly have the same Id). With the prototype function assigned to useLocalStorage the reference to storage the call to this.checker.getSymbolAtLocation( identifier ) does not return a symbol.

Actual behavior:

I am using the AST to identify identifiers which may be minified/shortened. The 1st and 2nd reference to storage gets shortened as it is a private property.

My expectation was that the reference to storage would have the same symbol ( not undefined ) as the other references to the storage property.

Reacted by Blake Niemyjski

Activity

  1. Todd Thomson (ToddThomson)
    changed the title [-]Reference to Identifier in function assigned to class prototype no symbol [/-] [+]Reference to Identifier in function assigned to class prototype has no symbol [/+] on Apr 12, 2016
  2. ToddThomson commented on Apr 12, 2016

    @ToddThomson
    Todd Thomson (ToddThomson)
    on Apr 12, 2016
    ContributorAuthor
    More actions

    Additionally, the resolution of the Type for this in:

    Configuration.prototype.useLocalStorage = function() {
        this.storage = "NodeFileStorageProvider"
    };
    

    results in Any. This was not what I was expecting.

  3. ToddThomson commented on Apr 12, 2016

    @ToddThomson
    Todd Thomson (ToddThomson)
    on Apr 12, 2016
    ContributorAuthor
    More actions

    Not sure why the type of this cannot be determined as in function checkThisExpression().

    Code fragment to use:

                    // If this is a function in a JS file, it might be a class method. Check if it's the RHS
                    // of a x.prototype.y = function [name]() { .... }
                    if (container.kind === SyntaxKind.FunctionExpression) {
                        if (getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) {
                            // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
                            const className = (((container.parent as BinaryExpression)   // x.prototype.y = f
                                .left as PropertyAccessExpression)       // x.prototype.y
                                .expression as PropertyAccessExpression) // x.prototype
                                .expression;                             // x
                            const classSymbol = checkExpression(className).symbol;
                            if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
                                return getInferredClassType(classSymbol);
                            }
                        }
                    }
    
  4. Todd Thomson (ToddThomson)
    changed the title [-]Reference to Identifier in function assigned to class prototype has no symbol [/-] [+]Question: Why does "this" not have a type in function assigned to class prototype [/+] on Apr 15, 2016
  5. ToddThomson commented on Apr 15, 2016

    @ToddThomson
    Todd Thomson (ToddThomson)
    on Apr 15, 2016
    ContributorAuthor
    More actions

    OK. I understand that this is resolved to the any Type when referenced within a function that has been assigned to the class prototype. This is the reason why there is no symbol for the identifier referenced by this.indentifierName. However, I am not clear why the Type cannot be resolved to the class type.
    In any event, I've written the code so that I can get the symbol of the identifier and thus shorten the identifier name occurrence, but I am curious as to the reason that TypeScript does not resolve the type of this to the class type?

  6. mhegazy commented on Apr 15, 2016

    @mhegazy
    Mohamed Hegazy (mhegazy)
    on Apr 15, 2016
    Contributor
    More actions

    I do not think there is really a good reason why it is the way it is. It is definitely possible to flow the this type as we flow the contextual type. i will bring this to discussion.

  7. Mohamed Hegazy (mhegazy)
    added
    SuggestionAn idea for TypeScriptAn idea for TypeScript
    In DiscussionNot yet reached consensusNot yet reached consensus
    on Apr 15, 2016
  8. sandersn commented on Apr 15, 2016

    @sandersn
    Nathan Shively-Sanders (sandersn)
    on Apr 15, 2016
    Member
    More actions

    In the meantime, the workaround is to give this for the method that's intended to be filled in later:

    class Configuration {
      // ...
      public useLocalStorage(this: this): void {
      }
    }

    Then contextual typing will pick up the type of this in the function you assign to Configuration.prototype.useLocalStorage.

  9. ToddThomson commented on Apr 16, 2016

    @ToddThomson
    Todd Thomson (ToddThomson)
    on Apr 16, 2016
    ContributorAuthor
    More actions

    Nathan Shively-Sanders (@sandersn) Thank-you. My context here is walking the AST to find identifiers to minify. In this particular case a user had an issue with his code ( this gist of it is above ) not being minified properly. As Mohamed Hegazy (@mhegazy) said, there is no reason why the type of this cannot be resolved in this context so I added that capability to my code.

  10. Mohamed Hegazy (mhegazy)
    added
    CommittedThe team has roadmapped this issueThe team has roadmapped this issue
    Accepting PRs
    Effort: Easy
    and removed
    In DiscussionNot yet reached consensusNot yet reached consensus
    on May 17, 2016
  11. Mohamed Hegazy (mhegazy)
    added this to the TypeScript 2.1 milestone on May 17, 2016
  12. Mohamed Hegazy (mhegazy)
    assigned
    Nathan Shively-Sanders (sandersn)
    on May 17, 2016
  13. mhegazy commented on May 17, 2016

    @mhegazy
    Mohamed Hegazy (mhegazy)
    on May 17, 2016
    Contributor
    More actions

    PRs are welcomed.

  14. Mohamed Hegazy (mhegazy)
    modified the milestones: This milestone has been deleted, TypeScript 2.1 on Sep 21, 2016
  15. niemyjski commented on Apr 12, 2017

    @niemyjski
    Blake Niemyjski (niemyjski)
    on Apr 12, 2017
    More actions

    Was any progress made on this?

  16. sandersn commented on Apr 12, 2017

    @sandersn
    Nathan Shively-Sanders (sandersn)
    on Apr 12, 2017
    Member
    More actions

    In 2.3 with --noImplicitThis, assigning a function to a prototype property should give this a contextual type, so

    Configuration.prototype.useLocalStorage = function() {
        this.storage = "NodeFileStorageProvider"
    };

    Should give the type Configuration to this in the body of the function.

    You can also use the new --strict flag, which includes --noImplicitThis.

  17. sandersn commented on Apr 12, 2017

    @sandersn
    Nathan Shively-Sanders (sandersn)
    on Apr 12, 2017
    Member
    More actions

    Fixed by #14141

  18. Nathan Shively-Sanders (sandersn)
    added
    FixedA PR has been merged for this issueA PR has been merged for this issue
    and removed
    Accepting PRs
    SuggestionAn idea for TypeScriptAn idea for TypeScript
    on Apr 12, 2017
  19. Nathan Shively-Sanders (sandersn)
    closed this as completedon Apr 12, 2017
  20. Mohamed Hegazy (mhegazy)
    modified the milestones: This milestone has been deleted, TypeScript 2.4 on Apr 26, 2018
  21. microsoft
    locked and limited conversation to collaborators on Jul 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @sandersn
    Nathan Shively-Sanders (sandersn)

Labels

CommittedThe team has roadmapped this issueThe team has roadmapped this issueFixedA PR has been merged for this issueA PR has been merged for this issue

Type

No type

Projects

No projects

    Milestone

    • TypeScript 2.4

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    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.