mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Revert the revert of explicitly typed special assignments (#25727)
* Revert "Revert "Explicitly typed special assignments are context sensitive (#25619)"" This reverts commit16676f2707. * Revert "Revert "Explicitly typed prototype assignments are context sensitive (#25688)"" This reverts commitff8c30d636.
This commit is contained in:
committed by
GitHub
parent
d9ed9177fe
commit
1edc975f15
@@ -4714,6 +4714,10 @@ namespace ts {
|
||||
// function/class/{} assignments are fresh declarations, not property assignments, so only add prototype assignments
|
||||
const specialDeclaration = getAssignedJavascriptInitializer(symbol.valueDeclaration);
|
||||
if (specialDeclaration) {
|
||||
const tag = getJSDocTypeTag(specialDeclaration);
|
||||
if (tag && tag.typeExpression) {
|
||||
return getTypeFromTypeNode(tag.typeExpression);
|
||||
}
|
||||
return getWidenedLiteralType(checkExpressionCached(specialDeclaration));
|
||||
}
|
||||
const types: Type[] = [];
|
||||
@@ -5081,7 +5085,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getJSInitializerType(decl: Node, symbol: Symbol, init: Expression | undefined): Type | undefined {
|
||||
if (init && isInJavaScriptFile(init) && isObjectLiteralExpression(init)) {
|
||||
if (init && isInJavaScriptFile(init) && isObjectLiteralExpression(init) && init.properties.length === 0) {
|
||||
const exports = createSymbolTable();
|
||||
while (isBinaryExpression(decl) || isPropertyAccessExpression(decl)) {
|
||||
const s = getSymbolOfNode(decl);
|
||||
@@ -15786,22 +15790,22 @@ namespace ts {
|
||||
}
|
||||
|
||||
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
|
||||
// Don't do this for special property assignments to avoid circularity.
|
||||
// Don't do this for special property assignments unless there is a type tag on the assignment, to avoid circularity from checking the right operand.
|
||||
function isContextSensitiveAssignment(binaryExpression: BinaryExpression): boolean {
|
||||
const kind = getSpecialPropertyAssignmentKind(binaryExpression);
|
||||
switch (kind) {
|
||||
case SpecialPropertyAssignmentKind.None:
|
||||
return true;
|
||||
case SpecialPropertyAssignmentKind.Property:
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
case SpecialPropertyAssignmentKind.Prototype:
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
// If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
|
||||
// See `bindStaticPropertyAssignment` in `binder.ts`.
|
||||
return !binaryExpression.left.symbol;
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
case SpecialPropertyAssignmentKind.ModuleExports:
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
return !binaryExpression.left.symbol || binaryExpression.left.symbol.valueDeclaration && !!getJSDocTypeTag(binaryExpression.left.symbol.valueDeclaration);
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
case SpecialPropertyAssignmentKind.Prototype:
|
||||
return false;
|
||||
case SpecialPropertyAssignmentKind.ModuleExports:
|
||||
return !binaryExpression.symbol || binaryExpression.symbol.valueDeclaration && !!getJSDocTypeTag(binaryExpression.symbol.valueDeclaration);
|
||||
default:
|
||||
return Debug.assertNever(kind);
|
||||
}
|
||||
|
||||
@@ -86,9 +86,9 @@ A.prototype = B.prototype = {
|
||||
>A : typeof A
|
||||
>prototype : { [x: string]: any; m(n: number): number; }
|
||||
>B.prototype = { /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; }
|
||||
>B.prototype : { [x: string]: any; }
|
||||
>B.prototype : { [x: string]: any; m(n: number): number; }
|
||||
>B : typeof B
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; m(n: number): number; }
|
||||
>{ /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; }
|
||||
|
||||
/** @param {number} n */
|
||||
|
||||
@@ -7,11 +7,11 @@ export function abc(a, b, c) { return 5; }
|
||||
>5 : 5
|
||||
|
||||
module.exports = { abc };
|
||||
>module.exports = { abc } : { [x: string]: any; abc: (a: any, b: any, c: any) => number; }
|
||||
>module.exports = { abc } : { abc: (a: any, b: any, c: any) => number; }
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{ abc } : { [x: string]: any; abc: (a: any, b: any, c: any) => number; }
|
||||
>{ abc } : { abc: (a: any, b: any, c: any) => number; }
|
||||
>abc : (a: any, b: any, c: any) => number
|
||||
|
||||
=== tests/cases/conformance/salsa/use.js ===
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
tests/cases/conformance/salsa/mod.js(5,7): error TS7006: Parameter 'n' implicitly has an 'any' type.
|
||||
tests/cases/conformance/salsa/test.js(52,7): error TS7006: Parameter 'n' implicitly has an 'any' type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/salsa/test.js (1 errors) ====
|
||||
/** @typedef {{
|
||||
status: 'done'
|
||||
m(n: number): void
|
||||
}} DoneStatus */
|
||||
|
||||
// property assignment
|
||||
var ns = {}
|
||||
/** @type {DoneStatus} */
|
||||
ns.x = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
|
||||
ns.x = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
ns.x
|
||||
|
||||
|
||||
// this-property assignment
|
||||
class Thing {
|
||||
constructor() {
|
||||
/** @type {DoneStatus} */
|
||||
this.s = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
}
|
||||
|
||||
fail() {
|
||||
this.s = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exports-property assignment
|
||||
|
||||
/** @type {DoneStatus} */
|
||||
exports.x = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
}
|
||||
exports.x
|
||||
|
||||
/** @type {DoneStatus} contextual typing is allowed, but module.exports.y: any.
|
||||
Guess it doesn't check the type tag? */
|
||||
module.exports.y = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
~
|
||||
!!! error TS7006: Parameter 'n' implicitly has an 'any' type.
|
||||
}
|
||||
module.exports.y
|
||||
|
||||
// prototype-property assignment
|
||||
/** @type {DoneStatus} */
|
||||
Thing.prototype.x = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
Thing.prototype.x
|
||||
|
||||
// prototype assignment
|
||||
function F() {
|
||||
}
|
||||
/** @type {DoneStatus} */
|
||||
F.prototype = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
}
|
||||
|
||||
==== tests/cases/conformance/salsa/mod.js (1 errors) ====
|
||||
// module.exports assignment
|
||||
/** @type {{ status: 'done', m(n: number): void }} */
|
||||
module.exports = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
~
|
||||
!!! error TS7006: Parameter 'n' implicitly has an 'any' type.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
=== tests/cases/conformance/salsa/test.js ===
|
||||
/** @typedef {{
|
||||
status: 'done'
|
||||
m(n: number): void
|
||||
}} DoneStatus */
|
||||
|
||||
// property assignment
|
||||
var ns = {}
|
||||
>ns : Symbol(ns, Decl(test.js, 6, 3))
|
||||
|
||||
/** @type {DoneStatus} */
|
||||
ns.x = {
|
||||
>ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
|
||||
>ns : Symbol(ns, Decl(test.js, 6, 3))
|
||||
>x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
|
||||
|
||||
status: 'done',
|
||||
>status : Symbol(status, Decl(test.js, 8, 8))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 9, 19))
|
||||
>n : Symbol(n, Decl(test.js, 10, 6))
|
||||
}
|
||||
|
||||
ns.x = {
|
||||
>ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
|
||||
>ns : Symbol(ns, Decl(test.js, 6, 3))
|
||||
>x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
|
||||
|
||||
status: 'done',
|
||||
>status : Symbol(status, Decl(test.js, 13, 8))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 14, 19))
|
||||
>n : Symbol(n, Decl(test.js, 15, 6))
|
||||
}
|
||||
ns.x
|
||||
>ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
|
||||
>ns : Symbol(ns, Decl(test.js, 6, 3))
|
||||
>x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1))
|
||||
|
||||
|
||||
// this-property assignment
|
||||
class Thing {
|
||||
>Thing : Symbol(Thing, Decl(test.js, 17, 4))
|
||||
|
||||
constructor() {
|
||||
/** @type {DoneStatus} */
|
||||
this.s = {
|
||||
>this.s : Symbol(Thing.s, Decl(test.js, 22, 19), Decl(test.js, 30, 12))
|
||||
>this : Symbol(Thing, Decl(test.js, 17, 4))
|
||||
>s : Symbol(Thing.s, Decl(test.js, 22, 19), Decl(test.js, 30, 12))
|
||||
|
||||
status: 'done',
|
||||
>status : Symbol(status, Decl(test.js, 24, 18))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 25, 27))
|
||||
>n : Symbol(n, Decl(test.js, 26, 14))
|
||||
}
|
||||
}
|
||||
|
||||
fail() {
|
||||
>fail : Symbol(Thing.fail, Decl(test.js, 28, 5))
|
||||
|
||||
this.s = {
|
||||
>this.s : Symbol(Thing.s, Decl(test.js, 22, 19), Decl(test.js, 30, 12))
|
||||
>this : Symbol(Thing, Decl(test.js, 17, 4))
|
||||
>s : Symbol(Thing.s, Decl(test.js, 22, 19), Decl(test.js, 30, 12))
|
||||
|
||||
status: 'done',
|
||||
>status : Symbol(status, Decl(test.js, 31, 18))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 32, 27))
|
||||
>n : Symbol(n, Decl(test.js, 33, 14))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exports-property assignment
|
||||
|
||||
/** @type {DoneStatus} */
|
||||
exports.x = {
|
||||
>exports.x : Symbol(x, Decl(test.js, 36, 1))
|
||||
>exports : Symbol(x, Decl(test.js, 36, 1))
|
||||
>x : Symbol(x, Decl(test.js, 36, 1))
|
||||
|
||||
status: "done",
|
||||
>status : Symbol(status, Decl(test.js, 41, 13))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 42, 19))
|
||||
>n : Symbol(n, Decl(test.js, 43, 6))
|
||||
}
|
||||
exports.x
|
||||
>exports.x : Symbol(x, Decl(test.js, 36, 1))
|
||||
>exports : Symbol("tests/cases/conformance/salsa/test", Decl(test.js, 0, 0))
|
||||
>x : Symbol(x, Decl(test.js, 36, 1))
|
||||
|
||||
/** @type {DoneStatus} contextual typing is allowed, but module.exports.y: any.
|
||||
Guess it doesn't check the type tag? */
|
||||
module.exports.y = {
|
||||
>module.exports : Symbol(y, Decl(test.js, 45, 9))
|
||||
>module : Symbol(module)
|
||||
>y : Symbol(y, Decl(test.js, 45, 9))
|
||||
|
||||
status: "done",
|
||||
>status : Symbol(status, Decl(test.js, 49, 20))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 50, 19))
|
||||
>n : Symbol(n, Decl(test.js, 51, 6))
|
||||
}
|
||||
module.exports.y
|
||||
>module : Symbol(module)
|
||||
|
||||
// prototype-property assignment
|
||||
/** @type {DoneStatus} */
|
||||
Thing.prototype.x = {
|
||||
>Thing.prototype.x : Symbol(Thing.x, Decl(test.js, 53, 16))
|
||||
>Thing.prototype : Symbol(Thing.x, Decl(test.js, 53, 16))
|
||||
>Thing : Symbol(Thing, Decl(test.js, 17, 4))
|
||||
>prototype : Symbol(Thing.prototype)
|
||||
>x : Symbol(Thing.x, Decl(test.js, 53, 16))
|
||||
|
||||
status: 'done',
|
||||
>status : Symbol(status, Decl(test.js, 57, 21))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 58, 19))
|
||||
>n : Symbol(n, Decl(test.js, 59, 6))
|
||||
}
|
||||
Thing.prototype.x
|
||||
>Thing.prototype.x : Symbol(Thing.x, Decl(test.js, 53, 16))
|
||||
>Thing.prototype : Symbol(Thing.prototype)
|
||||
>Thing : Symbol(Thing, Decl(test.js, 17, 4))
|
||||
>prototype : Symbol(Thing.prototype)
|
||||
>x : Symbol(Thing.x, Decl(test.js, 53, 16))
|
||||
|
||||
// prototype assignment
|
||||
function F() {
|
||||
>F : Symbol(F, Decl(test.js, 61, 17), Decl(test.js, 65, 1))
|
||||
}
|
||||
/** @type {DoneStatus} */
|
||||
F.prototype = {
|
||||
>F.prototype : Symbol(F.prototype, Decl(test.js, 65, 1))
|
||||
>F : Symbol(F, Decl(test.js, 61, 17), Decl(test.js, 65, 1))
|
||||
>prototype : Symbol(F.prototype, Decl(test.js, 65, 1))
|
||||
|
||||
status: "done",
|
||||
>status : Symbol(status, Decl(test.js, 67, 15))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(test.js, 68, 19))
|
||||
>n : Symbol(n, Decl(test.js, 69, 6))
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/mod.js ===
|
||||
// module.exports assignment
|
||||
/** @type {{ status: 'done', m(n: number): void }} */
|
||||
module.exports = {
|
||||
>module : Symbol(export=, Decl(mod.js, 0, 0))
|
||||
>exports : Symbol(export=, Decl(mod.js, 0, 0))
|
||||
|
||||
status: "done",
|
||||
>status : Symbol(status, Decl(mod.js, 2, 18))
|
||||
|
||||
m(n) { }
|
||||
>m : Symbol(m, Decl(mod.js, 3, 19))
|
||||
>n : Symbol(n, Decl(mod.js, 4, 6))
|
||||
}
|
||||
|
||||
208
tests/baselines/reference/contextualTypedSpecialAssignment.types
Normal file
208
tests/baselines/reference/contextualTypedSpecialAssignment.types
Normal file
@@ -0,0 +1,208 @@
|
||||
=== tests/cases/conformance/salsa/test.js ===
|
||||
/** @typedef {{
|
||||
status: 'done'
|
||||
m(n: number): void
|
||||
}} DoneStatus */
|
||||
|
||||
// property assignment
|
||||
var ns = {}
|
||||
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
/** @type {DoneStatus} */
|
||||
ns.x = {
|
||||
>ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
>ns.x : { status: "done"; m(n: number): void; }
|
||||
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
|
||||
>x : { status: "done"; m(n: number): void; }
|
||||
>{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
|
||||
status: 'done',
|
||||
>status : "done"
|
||||
>'done' : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: number) => void
|
||||
>n : number
|
||||
}
|
||||
|
||||
ns.x = {
|
||||
>ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
>ns.x : { status: "done"; m(n: number): void; }
|
||||
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
|
||||
>x : { status: "done"; m(n: number): void; }
|
||||
>{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
|
||||
status: 'done',
|
||||
>status : "done"
|
||||
>'done' : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: number) => void
|
||||
>n : number
|
||||
}
|
||||
ns.x
|
||||
>ns.x : { status: "done"; m(n: number): void; }
|
||||
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
|
||||
>x : { status: "done"; m(n: number): void; }
|
||||
|
||||
|
||||
// this-property assignment
|
||||
class Thing {
|
||||
>Thing : Thing
|
||||
|
||||
constructor() {
|
||||
/** @type {DoneStatus} */
|
||||
this.s = {
|
||||
>this.s = { status: 'done', m(n) { } } : { status: "done"; m(n: number): void; }
|
||||
>this.s : { status: "done"; m(n: number): void; }
|
||||
>this : this
|
||||
>s : { status: "done"; m(n: number): void; }
|
||||
>{ status: 'done', m(n) { } } : { status: "done"; m(n: number): void; }
|
||||
|
||||
status: 'done',
|
||||
>status : "done"
|
||||
>'done' : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: number) => void
|
||||
>n : number
|
||||
}
|
||||
}
|
||||
|
||||
fail() {
|
||||
>fail : () => void
|
||||
|
||||
this.s = {
|
||||
>this.s = { status: 'done', m(n) { } } : { status: "done"; m(n: number): void; }
|
||||
>this.s : { status: "done"; m(n: number): void; }
|
||||
>this : this
|
||||
>s : { status: "done"; m(n: number): void; }
|
||||
>{ status: 'done', m(n) { } } : { status: "done"; m(n: number): void; }
|
||||
|
||||
status: 'done',
|
||||
>status : "done"
|
||||
>'done' : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: number) => void
|
||||
>n : number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exports-property assignment
|
||||
|
||||
/** @type {DoneStatus} */
|
||||
exports.x = {
|
||||
>exports.x = { status: "done", m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
>exports.x : { status: "done"; m(n: number): void; }
|
||||
>exports : typeof import("tests/cases/conformance/salsa/test")
|
||||
>x : { status: "done"; m(n: number): void; }
|
||||
>{ status: "done", m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
|
||||
status: "done",
|
||||
>status : "done"
|
||||
>"done" : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: number) => void
|
||||
>n : number
|
||||
}
|
||||
exports.x
|
||||
>exports.x : { status: "done"; m(n: number): void; }
|
||||
>exports : typeof import("tests/cases/conformance/salsa/test")
|
||||
>x : { status: "done"; m(n: number): void; }
|
||||
|
||||
/** @type {DoneStatus} contextual typing is allowed, but module.exports.y: any.
|
||||
Guess it doesn't check the type tag? */
|
||||
module.exports.y = {
|
||||
>module.exports.y = { status: "done", m(n) { }} : { status: string; m(n: any): void; }
|
||||
>module.exports.y : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>y : any
|
||||
>{ status: "done", m(n) { }} : { status: string; m(n: any): void; }
|
||||
|
||||
status: "done",
|
||||
>status : string
|
||||
>"done" : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: any) => void
|
||||
>n : any
|
||||
}
|
||||
module.exports.y
|
||||
>module.exports.y : any
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>y : any
|
||||
|
||||
// prototype-property assignment
|
||||
/** @type {DoneStatus} */
|
||||
Thing.prototype.x = {
|
||||
>Thing.prototype.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
>Thing.prototype.x : { status: "done"; m(n: number): void; }
|
||||
>Thing.prototype : Thing
|
||||
>Thing : typeof Thing
|
||||
>prototype : Thing
|
||||
>x : { status: "done"; m(n: number): void; }
|
||||
>{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
|
||||
status: 'done',
|
||||
>status : "done"
|
||||
>'done' : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: number) => void
|
||||
>n : number
|
||||
}
|
||||
Thing.prototype.x
|
||||
>Thing.prototype.x : { status: "done"; m(n: number): void; }
|
||||
>Thing.prototype : Thing
|
||||
>Thing : typeof Thing
|
||||
>prototype : Thing
|
||||
>x : { status: "done"; m(n: number): void; }
|
||||
|
||||
// prototype assignment
|
||||
function F() {
|
||||
>F : typeof F
|
||||
}
|
||||
/** @type {DoneStatus} */
|
||||
F.prototype = {
|
||||
>F.prototype = { status: "done", m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
>F.prototype : { status: "done"; m(n: number): void; }
|
||||
>F : typeof F
|
||||
>prototype : { status: "done"; m(n: number): void; }
|
||||
>{ status: "done", m(n) { }} : { status: "done"; m(n: number): void; }
|
||||
|
||||
status: "done",
|
||||
>status : "done"
|
||||
>"done" : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: number) => void
|
||||
>n : number
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/salsa/mod.js ===
|
||||
// module.exports assignment
|
||||
/** @type {{ status: 'done', m(n: number): void }} */
|
||||
module.exports = {
|
||||
>module.exports = { status: "done", m(n) { }} : { status: string; m(n: any): void; }
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{ status: "done", m(n) { }} : { status: string; m(n: any): void; }
|
||||
|
||||
status: "done",
|
||||
>status : string
|
||||
>"done" : "done"
|
||||
|
||||
m(n) { }
|
||||
>m : (n: any) => void
|
||||
>n : any
|
||||
}
|
||||
|
||||
@@ -223,19 +223,19 @@ multipleDeclarationAlias5.func9 = function () { };
|
||||
>function () { } : () => void
|
||||
|
||||
var multipleDeclarationAlias6 = exports = module.exports = {};
|
||||
>multipleDeclarationAlias6 : { [x: string]: any; }
|
||||
>exports = module.exports = {} : { [x: string]: any; }
|
||||
>multipleDeclarationAlias6 : {}
|
||||
>exports = module.exports = {} : {}
|
||||
>exports : typeof import("tests/cases/conformance/salsa/b")
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
>{} : {}
|
||||
|
||||
multipleDeclarationAlias6.func10 = function () { };
|
||||
>multipleDeclarationAlias6.func10 = function () { } : () => void
|
||||
>multipleDeclarationAlias6.func10 : any
|
||||
>multipleDeclarationAlias6 : { [x: string]: any; }
|
||||
>multipleDeclarationAlias6 : {}
|
||||
>func10 : any
|
||||
>function () { } : () => void
|
||||
|
||||
@@ -294,13 +294,13 @@ module.exports.func12 = function () { };
|
||||
>function () { } : () => void
|
||||
|
||||
exports = module.exports = {};
|
||||
>exports = module.exports = {} : { [x: string]: any; }
|
||||
>exports = module.exports = {} : {}
|
||||
>exports : typeof import("tests/cases/conformance/salsa/b")
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
>{} : {}
|
||||
|
||||
exports.func13 = function () { };
|
||||
>exports.func13 = function () { } : () => void
|
||||
@@ -319,13 +319,13 @@ module.exports.func14 = function () { };
|
||||
>function () { } : () => void
|
||||
|
||||
exports = module.exports = {};
|
||||
>exports = module.exports = {} : { [x: string]: any; }
|
||||
>exports = module.exports = {} : {}
|
||||
>exports : typeof import("tests/cases/conformance/salsa/b")
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
>{} : {}
|
||||
|
||||
exports.func15 = function () { };
|
||||
>exports.func15 = function () { } : () => void
|
||||
@@ -369,11 +369,11 @@ module.exports.func18 = function () { };
|
||||
>function () { } : () => void
|
||||
|
||||
module.exports = {};
|
||||
>module.exports = {} : { [x: string]: any; }
|
||||
>module.exports = {} : {}
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>{} : { [x: string]: any; }
|
||||
>{} : {}
|
||||
|
||||
exports.func19 = function () { };
|
||||
>exports.func19 = function () { } : () => void
|
||||
|
||||
@@ -5,9 +5,9 @@ var Inner = function() {}
|
||||
|
||||
Inner.prototype = {
|
||||
>Inner.prototype = { m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
|
||||
>Inner.prototype : { [x: string]: any; }
|
||||
>Inner.prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>Inner : typeof Inner
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>{ m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
|
||||
|
||||
m() { },
|
||||
@@ -21,18 +21,18 @@ Inner.prototype = {
|
||||
Inner.prototype.j = 2
|
||||
>Inner.prototype.j = 2 : 2
|
||||
>Inner.prototype.j : any
|
||||
>Inner.prototype : { [x: string]: any; }
|
||||
>Inner.prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>Inner : typeof Inner
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>j : any
|
||||
>2 : 2
|
||||
|
||||
/** @type {string} */
|
||||
Inner.prototype.k;
|
||||
>Inner.prototype.k : any
|
||||
>Inner.prototype : { [x: string]: any; }
|
||||
>Inner.prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>Inner : typeof Inner
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>k : any
|
||||
|
||||
var inner = new Inner()
|
||||
|
||||
@@ -12,11 +12,11 @@ Outer.Inner = function() {}
|
||||
|
||||
Outer.Inner.prototype = {
|
||||
>Outer.Inner.prototype = { m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>Outer.Inner : typeof Inner
|
||||
>Outer : typeof Outer
|
||||
>Inner : typeof Inner
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>{ m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
|
||||
|
||||
m() { },
|
||||
@@ -30,22 +30,22 @@ Outer.Inner.prototype = {
|
||||
Outer.Inner.prototype.j = 2
|
||||
>Outer.Inner.prototype.j = 2 : 2
|
||||
>Outer.Inner.prototype.j : any
|
||||
>Outer.Inner.prototype : { [x: string]: any; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>Outer.Inner : typeof Inner
|
||||
>Outer : typeof Outer
|
||||
>Inner : typeof Inner
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>j : any
|
||||
>2 : 2
|
||||
|
||||
/** @type {string} */
|
||||
Outer.Inner.prototype.k;
|
||||
>Outer.Inner.prototype.k : any
|
||||
>Outer.Inner.prototype : { [x: string]: any; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>Outer.Inner : typeof Inner
|
||||
>Outer : typeof Outer
|
||||
>Inner : typeof Inner
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; m(): void; i: number; }
|
||||
>k : any
|
||||
|
||||
var inner = new Outer.Inner()
|
||||
|
||||
@@ -5,19 +5,19 @@ var Outer = {};
|
||||
|
||||
=== tests/cases/conformance/salsa/work.js ===
|
||||
Outer.Inner = function () {}
|
||||
>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer : typeof Outer
|
||||
>Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>function () {} : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
|
||||
Outer.Inner.prototype = {
|
||||
>Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; x: number; m(): void; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer : typeof Outer
|
||||
>Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>prototype : { [x: string]: any; }
|
||||
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>prototype : { [x: string]: any; x: number; m(): void; }
|
||||
>{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
|
||||
|
||||
x: 1,
|
||||
@@ -47,9 +47,9 @@ inner.m()
|
||||
var inno = new Outer.Inner()
|
||||
>inno : { [x: string]: any; x: number; m(): void; }
|
||||
>new Outer.Inner() : { [x: string]: any; x: number; m(): void; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer : typeof Outer
|
||||
>Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
|
||||
inno.x
|
||||
>inno.x : number
|
||||
|
||||
@@ -4,19 +4,19 @@ var Outer = {};
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
Outer.Inner = function () {}
|
||||
>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer : typeof Outer
|
||||
>Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>function () {} : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
|
||||
Outer.Inner.prototype = {
|
||||
>Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner.prototype : { [x: string]: any; x: number; m(): void; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer : typeof Outer
|
||||
>Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>prototype : { [x: string]: any; }
|
||||
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>prototype : { [x: string]: any; x: number; m(): void; }
|
||||
>{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
|
||||
|
||||
x: 1,
|
||||
@@ -45,9 +45,9 @@ inner.m()
|
||||
var inno = new Outer.Inner()
|
||||
>inno : { [x: string]: any; x: number; m(): void; }
|
||||
>new Outer.Inner() : { [x: string]: any; x: number; m(): void; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
>Outer : typeof Outer
|
||||
>Inner : { (): void; prototype: { [x: string]: any; }; }
|
||||
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
|
||||
|
||||
inno.x
|
||||
>inno.x : number
|
||||
|
||||
@@ -10,9 +10,9 @@ function C() { this.p = 1; }
|
||||
|
||||
C.prototype = { q: 2 };
|
||||
>C.prototype = { q: 2 } : { [x: string]: any; q: number; }
|
||||
>C.prototype : { [x: string]: any; }
|
||||
>C.prototype : { [x: string]: any; q: number; }
|
||||
>C : typeof C
|
||||
>prototype : { [x: string]: any; }
|
||||
>prototype : { [x: string]: any; q: number; }
|
||||
>{ q: 2 } : { [x: string]: any; q: number; }
|
||||
>q : number
|
||||
>2 : 2
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
// @noEmit: true
|
||||
// @Filename: test.js
|
||||
// @strict: true
|
||||
/** @typedef {{
|
||||
status: 'done'
|
||||
m(n: number): void
|
||||
}} DoneStatus */
|
||||
|
||||
// property assignment
|
||||
var ns = {}
|
||||
/** @type {DoneStatus} */
|
||||
ns.x = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
|
||||
ns.x = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
ns.x
|
||||
|
||||
|
||||
// this-property assignment
|
||||
class Thing {
|
||||
constructor() {
|
||||
/** @type {DoneStatus} */
|
||||
this.s = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
}
|
||||
|
||||
fail() {
|
||||
this.s = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exports-property assignment
|
||||
|
||||
/** @type {DoneStatus} */
|
||||
exports.x = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
}
|
||||
exports.x
|
||||
|
||||
/** @type {DoneStatus} contextual typing is allowed, but module.exports.y: any.
|
||||
Guess it doesn't check the type tag? */
|
||||
module.exports.y = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
}
|
||||
module.exports.y
|
||||
|
||||
// prototype-property assignment
|
||||
/** @type {DoneStatus} */
|
||||
Thing.prototype.x = {
|
||||
status: 'done',
|
||||
m(n) { }
|
||||
}
|
||||
Thing.prototype.x
|
||||
|
||||
// prototype assignment
|
||||
function F() {
|
||||
}
|
||||
/** @type {DoneStatus} */
|
||||
F.prototype = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
}
|
||||
|
||||
// @Filename: mod.js
|
||||
// module.exports assignment
|
||||
/** @type {{ status: 'done', m(n: number): void }} */
|
||||
module.exports = {
|
||||
status: "done",
|
||||
m(n) { }
|
||||
}
|
||||
Reference in New Issue
Block a user