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 #8024DescriptionTypeScript 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 Activitychanged 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, 2016ToddThomson commented 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. ToddThomson commented 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);
}
}
}
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, 2016ToddThomson commented 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? mhegazy commented on Apr 15, 2016 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. sandersn commented on Apr 15, 2016 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. ToddThomson commented 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. mhegazy commented on May 17, 2016 niemyjski commented on Apr 12, 2017 Was any progress made on this? sandersn commented on Apr 12, 2017 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. sandersn commented on Apr 12, 2017
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|