Fix this-type in prototype-assigned object literals (#26925)
* Fix this-type in prototype-assigned object literals Some cases were missing from tryGetThisTypeAt. Fixes #26831 * Lookup this in JS only for @constructor+prototype assignments
This commit is contained in:
parent
2f8a646f8e
commit
614423b287
|
@ -15809,30 +15809,27 @@ namespace ts {
|
|||
}
|
||||
|
||||
function tryGetThisTypeAt(node: Node, container = getThisContainer(node, /*includeArrowFunctions*/ false)): Type | undefined {
|
||||
const isInJS = isInJSFile(node);
|
||||
if (isFunctionLike(container) &&
|
||||
(!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
|
||||
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
|
||||
|
||||
// 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 &&
|
||||
container.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
getAssignmentDeclarationKind(container.parent as BinaryExpression) === AssignmentDeclarationKind.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 className = getClassNameFromPrototypeMethod(container);
|
||||
if (isInJS && className) {
|
||||
const classSymbol = checkExpression(className).symbol;
|
||||
if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
|
||||
return getFlowTypeOfReference(node, getInferredClassType(classSymbol));
|
||||
const classType = getJavascriptClassType(classSymbol);
|
||||
if (classType) {
|
||||
return getFlowTypeOfReference(node, classType);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if it's a constructor definition, can be either a variable decl or function decl
|
||||
// i.e.
|
||||
// * /** @constructor */ function [name]() { ... }
|
||||
// * /** @constructor */ var x = function() { ... }
|
||||
else if ((container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) &&
|
||||
else if (isInJS &&
|
||||
(container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) &&
|
||||
getJSDocClassTag(container)) {
|
||||
const classType = getJavascriptClassType(container.symbol);
|
||||
if (classType) {
|
||||
|
@ -15852,7 +15849,7 @@ namespace ts {
|
|||
return getFlowTypeOfReference(node, type);
|
||||
}
|
||||
|
||||
if (isInJSFile(node)) {
|
||||
if (isInJS) {
|
||||
const type = getTypeForThisExpressionFromJSDoc(container);
|
||||
if (type && type !== errorType) {
|
||||
return getFlowTypeOfReference(node, type);
|
||||
|
@ -15860,6 +15857,34 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getClassNameFromPrototypeMethod(container: Node) {
|
||||
// Check if it's the RHS of a x.prototype.y = function [name]() { .... }
|
||||
if (container.kind === SyntaxKind.FunctionExpression &&
|
||||
isBinaryExpression(container.parent) &&
|
||||
getAssignmentDeclarationKind(container.parent) === AssignmentDeclarationKind.PrototypeProperty) {
|
||||
// Get the 'x' of 'x.prototype.y = container'
|
||||
return ((container.parent // x.prototype.y = container
|
||||
.left as PropertyAccessExpression) // x.prototype.y
|
||||
.expression as PropertyAccessExpression) // x.prototype
|
||||
.expression; // x
|
||||
}
|
||||
// x.prototype = { method() { } }
|
||||
else if (container.kind === SyntaxKind.MethodDeclaration &&
|
||||
container.parent.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
isBinaryExpression(container.parent.parent) &&
|
||||
getAssignmentDeclarationKind(container.parent.parent) === AssignmentDeclarationKind.Prototype) {
|
||||
return (container.parent.parent.left as PropertyAccessExpression).expression;
|
||||
}
|
||||
// x.prototype = { method: function() { } }
|
||||
else if (container.kind === SyntaxKind.FunctionExpression &&
|
||||
container.parent.kind === SyntaxKind.PropertyAssignment &&
|
||||
container.parent.parent.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
isBinaryExpression(container.parent.parent.parent) &&
|
||||
getAssignmentDeclarationKind(container.parent.parent.parent) === AssignmentDeclarationKind.Prototype) {
|
||||
return (container.parent.parent.parent.left as PropertyAccessExpression).expression;
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeForThisExpressionFromJSDoc(node: Node) {
|
||||
const jsdocType = getJSDocType(node);
|
||||
if (jsdocType && jsdocType.kind === SyntaxKind.JSDocFunctionType) {
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
tests/cases/conformance/jsdoc/a.js(18,21): error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'.
|
||||
tests/cases/conformance/jsdoc/a.js(39,21): error TS2339: Property '_map' does not exist on type '{ get: (key: K) => V; }'.
|
||||
tests/cases/conformance/jsdoc/a.js(61,21): error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/a.js (3 errors) ====
|
||||
/**
|
||||
* Should work for function declarations
|
||||
* @constructor
|
||||
* @template {string} K
|
||||
* @template V
|
||||
*/
|
||||
function Multimap() {
|
||||
/** @type {Object<string, V>} TODO: Remove the prototype from the fresh object */
|
||||
this._map = {};
|
||||
};
|
||||
|
||||
Multimap.prototype = {
|
||||
/**
|
||||
* @param {K} key the key ok
|
||||
* @returns {V} the value ok
|
||||
*/
|
||||
get(key) {
|
||||
return this._map[key + ''];
|
||||
~~~~
|
||||
!!! error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should work for initialisers too
|
||||
* @constructor
|
||||
* @template {string} K
|
||||
* @template V
|
||||
*/
|
||||
var Multimap2 = function() {
|
||||
/** @type {Object<string, V>} TODO: Remove the prototype from the fresh object */
|
||||
this._map = {};
|
||||
};
|
||||
|
||||
Multimap2.prototype = {
|
||||
/**
|
||||
* @param {K} key the key ok
|
||||
* @returns {V} the value ok
|
||||
*/
|
||||
get: function(key) {
|
||||
return this._map[key + ''];
|
||||
~~~~
|
||||
!!! error TS2339: Property '_map' does not exist on type '{ get: (key: K) => V; }'.
|
||||
}
|
||||
}
|
||||
|
||||
var Ns = {};
|
||||
/**
|
||||
* Should work for expando-namespaced initialisers too
|
||||
* @constructor
|
||||
* @template {string} K
|
||||
* @template V
|
||||
*/
|
||||
Ns.Multimap3 = function() {
|
||||
/** @type {Object<string, V>} TODO: Remove the prototype from the fresh object */
|
||||
this._map = {};
|
||||
};
|
||||
|
||||
Ns.Multimap3.prototype = {
|
||||
/**
|
||||
* @param {K} key the key ok
|
||||
* @returns {V} the value ok
|
||||
*/
|
||||
get(key) {
|
||||
return this._map[key + ''];
|
||||
~~~~
|
||||
!!! error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +29,8 @@ Multimap.prototype = {
|
|||
>key : Symbol(key, Decl(a.js, 16, 8))
|
||||
|
||||
return this._map[key + ''];
|
||||
>this : Symbol(__object, Decl(a.js, 11, 20))
|
||||
>this._map : Symbol(Multimap._map, Decl(a.js, 6, 21))
|
||||
>_map : Symbol(Multimap._map, Decl(a.js, 6, 21))
|
||||
>key : Symbol(key, Decl(a.js, 16, 8))
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +65,8 @@ Multimap2.prototype = {
|
|||
>key : Symbol(key, Decl(a.js, 37, 18))
|
||||
|
||||
return this._map[key + ''];
|
||||
>this : Symbol(__object, Decl(a.js, 32, 21))
|
||||
>this._map : Symbol(Multimap2._map, Decl(a.js, 27, 28))
|
||||
>_map : Symbol(Multimap2._map, Decl(a.js, 27, 28))
|
||||
>key : Symbol(key, Decl(a.js, 37, 18))
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +108,8 @@ Ns.Multimap3.prototype = {
|
|||
>key : Symbol(key, Decl(a.js, 59, 8))
|
||||
|
||||
return this._map[key + ''];
|
||||
>this : Symbol(__object, Decl(a.js, 54, 24))
|
||||
>this._map : Symbol(Multimap3._map, Decl(a.js, 49, 27))
|
||||
>_map : Symbol(Multimap3._map, Decl(a.js, 49, 27))
|
||||
>key : Symbol(key, Decl(a.js, 59, 8))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,10 +34,10 @@ Multimap.prototype = {
|
|||
>key : K
|
||||
|
||||
return this._map[key + ''];
|
||||
>this._map[key + ''] : any
|
||||
>this._map : any
|
||||
>this : { get(key: K): V; }
|
||||
>_map : any
|
||||
>this._map[key + ''] : V
|
||||
>this._map : { [x: string]: V; }
|
||||
>this : Multimap & { get(key: K): V; }
|
||||
>_map : { [x: string]: V; }
|
||||
>key + '' : string
|
||||
>key : K
|
||||
>'' : ""
|
||||
|
@ -81,10 +81,10 @@ Multimap2.prototype = {
|
|||
>key : K
|
||||
|
||||
return this._map[key + ''];
|
||||
>this._map[key + ''] : any
|
||||
>this._map : any
|
||||
>this : { get: (key: K) => V; }
|
||||
>_map : any
|
||||
>this._map[key + ''] : V
|
||||
>this._map : { [x: string]: V; }
|
||||
>this : Multimap2 & { get: (key: K) => V; }
|
||||
>_map : { [x: string]: V; }
|
||||
>key + '' : string
|
||||
>key : K
|
||||
>'' : ""
|
||||
|
@ -136,10 +136,10 @@ Ns.Multimap3.prototype = {
|
|||
>key : K
|
||||
|
||||
return this._map[key + ''];
|
||||
>this._map[key + ''] : any
|
||||
>this._map : any
|
||||
>this : { get(key: K): V; }
|
||||
>_map : any
|
||||
>this._map[key + ''] : V
|
||||
>this._map : { [x: string]: V; }
|
||||
>this : Multimap3 & { get(key: K): V; }
|
||||
>_map : { [x: string]: V; }
|
||||
>key + '' : string
|
||||
>key : K
|
||||
>'' : ""
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
tests/cases/conformance/salsa/a.js(27,20): error TS2339: Property 'addon' does not exist on type '{ set: () => void; get(): void; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/salsa/a.js (1 errors) ====
|
||||
// all references to _map, set, get, addon should be ok
|
||||
|
||||
/** @constructor */
|
||||
var Multimap = function() {
|
||||
this._map = {};
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
};
|
||||
|
||||
Multimap.prototype = {
|
||||
set: function() {
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
},
|
||||
get() {
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
}
|
||||
}
|
||||
|
||||
Multimap.prototype.addon = function () {
|
||||
~~~~~
|
||||
!!! error TS2339: Property 'addon' does not exist on type '{ set: () => void; get(): void; }'.
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
}
|
||||
|
||||
var mm = new Multimap();
|
||||
mm._map
|
||||
mm.set
|
||||
mm.get
|
||||
mm.addon
|
||||
|
122
tests/baselines/reference/typeFromPrototypeAssignment.symbols
Normal file
122
tests/baselines/reference/typeFromPrototypeAssignment.symbols
Normal file
|
@ -0,0 +1,122 @@
|
|||
=== tests/cases/conformance/salsa/a.js ===
|
||||
// all references to _map, set, get, addon should be ok
|
||||
|
||||
/** @constructor */
|
||||
var Multimap = function() {
|
||||
>Multimap : Symbol(Multimap, Decl(a.js, 3, 3), Decl(a.js, 9, 2))
|
||||
|
||||
this._map = {};
|
||||
>this._map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
>_map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
|
||||
this._map
|
||||
>this._map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
>_map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
|
||||
this.set
|
||||
>this.set : Symbol(set, Decl(a.js, 11, 22))
|
||||
>set : Symbol(set, Decl(a.js, 11, 22))
|
||||
|
||||
this.get
|
||||
>this.get : Symbol(get, Decl(a.js, 17, 6))
|
||||
>get : Symbol(get, Decl(a.js, 17, 6))
|
||||
|
||||
this.addon
|
||||
>this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
>addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
|
||||
};
|
||||
|
||||
Multimap.prototype = {
|
||||
>Multimap.prototype : Symbol(Multimap.prototype, Decl(a.js, 9, 2))
|
||||
>Multimap : Symbol(Multimap, Decl(a.js, 3, 3), Decl(a.js, 9, 2))
|
||||
>prototype : Symbol(Multimap.prototype, Decl(a.js, 9, 2))
|
||||
|
||||
set: function() {
|
||||
>set : Symbol(set, Decl(a.js, 11, 22))
|
||||
|
||||
this._map
|
||||
>this._map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
>_map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
|
||||
this.set
|
||||
>this.set : Symbol(set, Decl(a.js, 11, 22))
|
||||
>set : Symbol(set, Decl(a.js, 11, 22))
|
||||
|
||||
this.get
|
||||
>this.get : Symbol(get, Decl(a.js, 17, 6))
|
||||
>get : Symbol(get, Decl(a.js, 17, 6))
|
||||
|
||||
this.addon
|
||||
>this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
>addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
|
||||
},
|
||||
get() {
|
||||
>get : Symbol(get, Decl(a.js, 17, 6))
|
||||
|
||||
this._map
|
||||
>this._map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
>_map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
|
||||
this.set
|
||||
>this.set : Symbol(set, Decl(a.js, 11, 22))
|
||||
>set : Symbol(set, Decl(a.js, 11, 22))
|
||||
|
||||
this.get
|
||||
>this.get : Symbol(get, Decl(a.js, 17, 6))
|
||||
>get : Symbol(get, Decl(a.js, 17, 6))
|
||||
|
||||
this.addon
|
||||
>this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
>addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
}
|
||||
}
|
||||
|
||||
Multimap.prototype.addon = function () {
|
||||
>Multimap.prototype : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
>Multimap : Symbol(Multimap, Decl(a.js, 3, 3), Decl(a.js, 9, 2))
|
||||
>prototype : Symbol(Multimap.prototype, Decl(a.js, 9, 2))
|
||||
>addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
|
||||
this._map
|
||||
>this._map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
>_map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
|
||||
this.set
|
||||
>this.set : Symbol(set, Decl(a.js, 11, 22))
|
||||
>set : Symbol(set, Decl(a.js, 11, 22))
|
||||
|
||||
this.get
|
||||
>this.get : Symbol(get, Decl(a.js, 17, 6))
|
||||
>get : Symbol(get, Decl(a.js, 17, 6))
|
||||
|
||||
this.addon
|
||||
>this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
>addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
}
|
||||
|
||||
var mm = new Multimap();
|
||||
>mm : Symbol(mm, Decl(a.js, 33, 3))
|
||||
>Multimap : Symbol(Multimap, Decl(a.js, 3, 3), Decl(a.js, 9, 2))
|
||||
|
||||
mm._map
|
||||
>mm._map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
>mm : Symbol(mm, Decl(a.js, 33, 3))
|
||||
>_map : Symbol(Multimap._map, Decl(a.js, 3, 27))
|
||||
|
||||
mm.set
|
||||
>mm.set : Symbol(set, Decl(a.js, 11, 22))
|
||||
>mm : Symbol(mm, Decl(a.js, 33, 3))
|
||||
>set : Symbol(set, Decl(a.js, 11, 22))
|
||||
|
||||
mm.get
|
||||
>mm.get : Symbol(get, Decl(a.js, 17, 6))
|
||||
>mm : Symbol(mm, Decl(a.js, 33, 3))
|
||||
>get : Symbol(get, Decl(a.js, 17, 6))
|
||||
|
||||
mm.addon
|
||||
>mm.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
>mm : Symbol(mm, Decl(a.js, 33, 3))
|
||||
>addon : Symbol(Multimap.addon, Decl(a.js, 24, 1))
|
||||
|
149
tests/baselines/reference/typeFromPrototypeAssignment.types
Normal file
149
tests/baselines/reference/typeFromPrototypeAssignment.types
Normal file
|
@ -0,0 +1,149 @@
|
|||
=== tests/cases/conformance/salsa/a.js ===
|
||||
// all references to _map, set, get, addon should be ok
|
||||
|
||||
/** @constructor */
|
||||
var Multimap = function() {
|
||||
>Multimap : typeof Multimap
|
||||
>function() { this._map = {}; this._map this.set this.get this.addon} : typeof Multimap
|
||||
|
||||
this._map = {};
|
||||
>this._map = {} : {}
|
||||
>this._map : {}
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>_map : {}
|
||||
>{} : {}
|
||||
|
||||
this._map
|
||||
>this._map : {}
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>_map : {}
|
||||
|
||||
this.set
|
||||
>this.set : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>set : () => void
|
||||
|
||||
this.get
|
||||
>this.get : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>get : () => void
|
||||
|
||||
this.addon
|
||||
>this.addon : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>addon : () => void
|
||||
|
||||
};
|
||||
|
||||
Multimap.prototype = {
|
||||
>Multimap.prototype = { set: function() { this._map this.set this.get this.addon }, get() { this._map this.set this.get this.addon }} : { set: () => void; get(): void; }
|
||||
>Multimap.prototype : { set: () => void; get(): void; }
|
||||
>Multimap : typeof Multimap
|
||||
>prototype : { set: () => void; get(): void; }
|
||||
>{ set: function() { this._map this.set this.get this.addon }, get() { this._map this.set this.get this.addon }} : { set: () => void; get(): void; }
|
||||
|
||||
set: function() {
|
||||
>set : () => void
|
||||
>function() { this._map this.set this.get this.addon } : () => void
|
||||
|
||||
this._map
|
||||
>this._map : {}
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>_map : {}
|
||||
|
||||
this.set
|
||||
>this.set : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>set : () => void
|
||||
|
||||
this.get
|
||||
>this.get : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>get : () => void
|
||||
|
||||
this.addon
|
||||
>this.addon : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>addon : () => void
|
||||
|
||||
},
|
||||
get() {
|
||||
>get : () => void
|
||||
|
||||
this._map
|
||||
>this._map : {}
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>_map : {}
|
||||
|
||||
this.set
|
||||
>this.set : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>set : () => void
|
||||
|
||||
this.get
|
||||
>this.get : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>get : () => void
|
||||
|
||||
this.addon
|
||||
>this.addon : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>addon : () => void
|
||||
}
|
||||
}
|
||||
|
||||
Multimap.prototype.addon = function () {
|
||||
>Multimap.prototype.addon = function () { this._map this.set this.get this.addon} : () => void
|
||||
>Multimap.prototype.addon : any
|
||||
>Multimap.prototype : { set: () => void; get(): void; }
|
||||
>Multimap : typeof Multimap
|
||||
>prototype : { set: () => void; get(): void; }
|
||||
>addon : any
|
||||
>function () { this._map this.set this.get this.addon} : () => void
|
||||
|
||||
this._map
|
||||
>this._map : {}
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>_map : {}
|
||||
|
||||
this.set
|
||||
>this.set : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>set : () => void
|
||||
|
||||
this.get
|
||||
>this.get : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>get : () => void
|
||||
|
||||
this.addon
|
||||
>this.addon : () => void
|
||||
>this : Multimap & { set: () => void; get(): void; }
|
||||
>addon : () => void
|
||||
}
|
||||
|
||||
var mm = new Multimap();
|
||||
>mm : Multimap & { set: () => void; get(): void; }
|
||||
>new Multimap() : Multimap & { set: () => void; get(): void; }
|
||||
>Multimap : typeof Multimap
|
||||
|
||||
mm._map
|
||||
>mm._map : {}
|
||||
>mm : Multimap & { set: () => void; get(): void; }
|
||||
>_map : {}
|
||||
|
||||
mm.set
|
||||
>mm.set : () => void
|
||||
>mm : Multimap & { set: () => void; get(): void; }
|
||||
>set : () => void
|
||||
|
||||
mm.get
|
||||
>mm.get : () => void
|
||||
>mm : Multimap & { set: () => void; get(): void; }
|
||||
>get : () => void
|
||||
|
||||
mm.addon
|
||||
>mm.addon : () => void
|
||||
>mm : Multimap & { set: () => void; get(): void; }
|
||||
>addon : () => void
|
||||
|
44
tests/cases/conformance/salsa/typeFromPrototypeAssignment.ts
Normal file
44
tests/cases/conformance/salsa/typeFromPrototypeAssignment.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: a.js
|
||||
// @strict: true
|
||||
|
||||
// all references to _map, set, get, addon should be ok
|
||||
|
||||
/** @constructor */
|
||||
var Multimap = function() {
|
||||
this._map = {};
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
};
|
||||
|
||||
Multimap.prototype = {
|
||||
set: function() {
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
},
|
||||
get() {
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
}
|
||||
}
|
||||
|
||||
Multimap.prototype.addon = function () {
|
||||
this._map
|
||||
this.set
|
||||
this.get
|
||||
this.addon
|
||||
}
|
||||
|
||||
var mm = new Multimap();
|
||||
mm._map
|
||||
mm.set
|
||||
mm.get
|
||||
mm.addon
|
Loading…
Reference in a new issue