From 277947c354480eb30862e6c27ba1342ef0e09021 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Fri, 17 Apr 2020 16:29:14 -0400 Subject: [PATCH 1/3] Adds support for looking up past Blocks in expando objects --- src/compiler/binder.ts | 4 +- .../reference/topLevelBlockExpando.js | 22 ++++++++++ .../reference/topLevelBlockExpando.symbols | 38 ++++++++++++++++ .../reference/topLevelBlockExpando.types | 44 +++++++++++++++++++ tests/cases/compiler/topLevelBlockExpando.ts | 12 +++++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/topLevelBlockExpando.js create mode 100644 tests/baselines/reference/topLevelBlockExpando.symbols create mode 100644 tests/baselines/reference/topLevelBlockExpando.types create mode 100644 tests/cases/compiler/topLevelBlockExpando.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 3cde8be7ea115..ca272ea0b1611 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2974,7 +2974,7 @@ namespace ts { function bindSpecialPropertyAssignment(node: BindablePropertyAssignmentExpression) { // Class declarations in Typescript do not allow property declarations - const parentSymbol = lookupSymbolForPropertyAccess(node.left.expression); + const parentSymbol = lookupSymbolForPropertyAccess(node.left.expression, container) || lookupSymbolForPropertyAccess(node.left.expression, blockScopeContainer) ; if (!isInJSFile(node) && !isFunctionSymbol(parentSymbol)) { return; } @@ -3083,7 +3083,7 @@ namespace ts { } function bindPropertyAssignment(name: BindableStaticNameExpression, propertyAccess: BindableStaticAccessExpression, isPrototypeProperty: boolean, containerIsClass: boolean) { - let namespaceSymbol = lookupSymbolForPropertyAccess(name); + let namespaceSymbol = lookupSymbolForPropertyAccess(name, container) || lookupSymbolForPropertyAccess(name, blockScopeContainer); const isToplevel = isTopLevelNamespaceAssignment(propertyAccess); namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty, containerIsClass); bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty); diff --git a/tests/baselines/reference/topLevelBlockExpando.js b/tests/baselines/reference/topLevelBlockExpando.js new file mode 100644 index 0000000000000..6df27d58aae66 --- /dev/null +++ b/tests/baselines/reference/topLevelBlockExpando.js @@ -0,0 +1,22 @@ +//// [topLevelBlockExpando.ts] +// https://github.com/microsoft/TypeScript/issues/31972 +interface Person { + first: string; + last: string; +} + +{ + const dice = () => Math.floor(Math.random() * 6); + dice.first = 'Rando'; + dice.last = 'Calrissian'; + const diceP: Person = dice; +} + + +//// [topLevelBlockExpando.js] +{ + var dice = function () { return Math.floor(Math.random() * 6); }; + dice.first = 'Rando'; + dice.last = 'Calrissian'; + var diceP = dice; +} diff --git a/tests/baselines/reference/topLevelBlockExpando.symbols b/tests/baselines/reference/topLevelBlockExpando.symbols new file mode 100644 index 0000000000000..2c8e4b1fa402f --- /dev/null +++ b/tests/baselines/reference/topLevelBlockExpando.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/topLevelBlockExpando.ts === +// https://github.com/microsoft/TypeScript/issues/31972 +interface Person { +>Person : Symbol(Person, Decl(topLevelBlockExpando.ts, 0, 0)) + + first: string; +>first : Symbol(Person.first, Decl(topLevelBlockExpando.ts, 1, 18)) + + last: string; +>last : Symbol(Person.last, Decl(topLevelBlockExpando.ts, 2, 16)) +} + +{ + const dice = () => Math.floor(Math.random() * 6); +>dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) +>Math.floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + dice.first = 'Rando'; +>dice.first : Symbol(dice.first, Decl(topLevelBlockExpando.ts, 7, 51)) +>dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) +>first : Symbol(dice.first, Decl(topLevelBlockExpando.ts, 7, 51)) + + dice.last = 'Calrissian'; +>dice.last : Symbol(dice.last, Decl(topLevelBlockExpando.ts, 8, 23)) +>dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) +>last : Symbol(dice.last, Decl(topLevelBlockExpando.ts, 8, 23)) + + const diceP: Person = dice; +>diceP : Symbol(diceP, Decl(topLevelBlockExpando.ts, 10, 7)) +>Person : Symbol(Person, Decl(topLevelBlockExpando.ts, 0, 0)) +>dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) +} + diff --git a/tests/baselines/reference/topLevelBlockExpando.types b/tests/baselines/reference/topLevelBlockExpando.types new file mode 100644 index 0000000000000..392223291292a --- /dev/null +++ b/tests/baselines/reference/topLevelBlockExpando.types @@ -0,0 +1,44 @@ +=== tests/cases/compiler/topLevelBlockExpando.ts === +// https://github.com/microsoft/TypeScript/issues/31972 +interface Person { + first: string; +>first : string + + last: string; +>last : string +} + +{ + const dice = () => Math.floor(Math.random() * 6); +>dice : { (): number; first: string; last: string; } +>() => Math.floor(Math.random() * 6) : { (): number; first: string; last: string; } +>Math.floor(Math.random() * 6) : number +>Math.floor : (x: number) => number +>Math : Math +>floor : (x: number) => number +>Math.random() * 6 : number +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>6 : 6 + + dice.first = 'Rando'; +>dice.first = 'Rando' : "Rando" +>dice.first : string +>dice : { (): number; first: string; last: string; } +>first : string +>'Rando' : "Rando" + + dice.last = 'Calrissian'; +>dice.last = 'Calrissian' : "Calrissian" +>dice.last : string +>dice : { (): number; first: string; last: string; } +>last : string +>'Calrissian' : "Calrissian" + + const diceP: Person = dice; +>diceP : Person +>dice : { (): number; first: string; last: string; } +} + diff --git a/tests/cases/compiler/topLevelBlockExpando.ts b/tests/cases/compiler/topLevelBlockExpando.ts new file mode 100644 index 0000000000000..ca066b5464efb --- /dev/null +++ b/tests/cases/compiler/topLevelBlockExpando.ts @@ -0,0 +1,12 @@ +// https://github.com/microsoft/TypeScript/issues/31972 +interface Person { + first: string; + last: string; +} + +{ + const dice = () => Math.floor(Math.random() * 6); + dice.first = 'Rando'; + dice.last = 'Calrissian'; + const diceP: Person = dice; +} From ee1ae84c94e8d719f701c9af6b30f9a4355208f8 Mon Sep 17 00:00:00 2001 From: orta therox Date: Wed, 22 Apr 2020 12:39:03 -0400 Subject: [PATCH 2/3] Adds JS tests to validate the JS parsing also works --- .../reference/topLevelBlockExpando.errors.txt | 59 ++++++++++++ .../reference/topLevelBlockExpando.js | 22 ----- .../reference/topLevelBlockExpando.symbols | 92 ++++++++++++++++--- .../reference/topLevelBlockExpando.types | 90 +++++++++++++++++- tests/cases/compiler/topLevelBlockExpando.ts | 37 ++++++++ 5 files changed, 263 insertions(+), 37 deletions(-) create mode 100644 tests/baselines/reference/topLevelBlockExpando.errors.txt delete mode 100644 tests/baselines/reference/topLevelBlockExpando.js diff --git a/tests/baselines/reference/topLevelBlockExpando.errors.txt b/tests/baselines/reference/topLevelBlockExpando.errors.txt new file mode 100644 index 0000000000000..1698558eb2844 --- /dev/null +++ b/tests/baselines/reference/topLevelBlockExpando.errors.txt @@ -0,0 +1,59 @@ +tests/cases/compiler/check.js(22,8): error TS2339: Property 'first' does not exist on type '() => number'. +tests/cases/compiler/check.js(23,8): error TS2339: Property 'last' does not exist on type '() => number'. +tests/cases/compiler/check.js(25,17): error TS2345: Argument of type '() => number' is not assignable to parameter of type 'Human'. + Type '() => number' is missing the following properties from type 'Human': first, last + + +==== tests/cases/compiler/check.ts (0 errors) ==== + // + + + + // https://github.com/microsoft/TypeScript/issues/31972 + interface Person { + first: string; + last: string; + } + + { + const dice = () => Math.floor(Math.random() * 6); + dice.first = 'Rando'; + dice.last = 'Calrissian'; + const diceP: Person = dice; + } + +==== tests/cases/compiler/check.js (3 errors) ==== + // Creates a type { first:string, last: string } + /** + * @typedef {Object} Human - creates a new type named 'SpecialType' + * @property {string} first - a string property of SpecialType + * @property {string} last - a number property of SpecialType + */ + + /** + * @param {Human} param used as a validation tool + */ + function doHumanThings(param) {} + + const dice = () => Math.floor(Math.random() * 6); + dice.first = 'Rando'; + dice.last = 'Calrissian'; + + doHumanThings(dice) + + // but inside a block... you can't call iut a human + { + const dice = () => Math.floor(Math.random() * 6); + dice.first = 'Rando'; + ~~~~~ +!!! error TS2339: Property 'first' does not exist on type '() => number'. + dice.last = 'Calrissian'; + ~~~~ +!!! error TS2339: Property 'last' does not exist on type '() => number'. + + doHumanThings(dice) + ~~~~ +!!! error TS2345: Argument of type '() => number' is not assignable to parameter of type 'Human'. +!!! error TS2345: Type '() => number' is missing the following properties from type 'Human': first, last + } + \ No newline at end of file diff --git a/tests/baselines/reference/topLevelBlockExpando.js b/tests/baselines/reference/topLevelBlockExpando.js deleted file mode 100644 index 6df27d58aae66..0000000000000 --- a/tests/baselines/reference/topLevelBlockExpando.js +++ /dev/null @@ -1,22 +0,0 @@ -//// [topLevelBlockExpando.ts] -// https://github.com/microsoft/TypeScript/issues/31972 -interface Person { - first: string; - last: string; -} - -{ - const dice = () => Math.floor(Math.random() * 6); - dice.first = 'Rando'; - dice.last = 'Calrissian'; - const diceP: Person = dice; -} - - -//// [topLevelBlockExpando.js] -{ - var dice = function () { return Math.floor(Math.random() * 6); }; - dice.first = 'Rando'; - dice.last = 'Calrissian'; - var diceP = dice; -} diff --git a/tests/baselines/reference/topLevelBlockExpando.symbols b/tests/baselines/reference/topLevelBlockExpando.symbols index 2c8e4b1fa402f..41a4327cb82a7 100644 --- a/tests/baselines/reference/topLevelBlockExpando.symbols +++ b/tests/baselines/reference/topLevelBlockExpando.symbols @@ -1,18 +1,22 @@ -=== tests/cases/compiler/topLevelBlockExpando.ts === +=== tests/cases/compiler/check.ts === +// + + + // https://github.com/microsoft/TypeScript/issues/31972 interface Person { ->Person : Symbol(Person, Decl(topLevelBlockExpando.ts, 0, 0)) +>Person : Symbol(Person, Decl(check.ts, 0, 0)) first: string; ->first : Symbol(Person.first, Decl(topLevelBlockExpando.ts, 1, 18)) +>first : Symbol(Person.first, Decl(check.ts, 5, 18)) last: string; ->last : Symbol(Person.last, Decl(topLevelBlockExpando.ts, 2, 16)) +>last : Symbol(Person.last, Decl(check.ts, 6, 16)) } { const dice = () => Math.floor(Math.random() * 6); ->dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) +>dice : Symbol(dice, Decl(check.ts, 11, 7)) >Math.floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) >Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) @@ -21,18 +25,78 @@ interface Person { >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) dice.first = 'Rando'; ->dice.first : Symbol(dice.first, Decl(topLevelBlockExpando.ts, 7, 51)) ->dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) ->first : Symbol(dice.first, Decl(topLevelBlockExpando.ts, 7, 51)) +>dice.first : Symbol(dice.first, Decl(check.ts, 11, 51)) +>dice : Symbol(dice, Decl(check.ts, 11, 7)) +>first : Symbol(dice.first, Decl(check.ts, 11, 51)) dice.last = 'Calrissian'; ->dice.last : Symbol(dice.last, Decl(topLevelBlockExpando.ts, 8, 23)) ->dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) ->last : Symbol(dice.last, Decl(topLevelBlockExpando.ts, 8, 23)) +>dice.last : Symbol(dice.last, Decl(check.ts, 12, 23)) +>dice : Symbol(dice, Decl(check.ts, 11, 7)) +>last : Symbol(dice.last, Decl(check.ts, 12, 23)) const diceP: Person = dice; ->diceP : Symbol(diceP, Decl(topLevelBlockExpando.ts, 10, 7)) ->Person : Symbol(Person, Decl(topLevelBlockExpando.ts, 0, 0)) ->dice : Symbol(dice, Decl(topLevelBlockExpando.ts, 7, 7)) +>diceP : Symbol(diceP, Decl(check.ts, 14, 7)) +>Person : Symbol(Person, Decl(check.ts, 0, 0)) +>dice : Symbol(dice, Decl(check.ts, 11, 7)) +} + +=== tests/cases/compiler/check.js === +// Creates a type { first:string, last: string } +/** + * @typedef {Object} Human - creates a new type named 'SpecialType' + * @property {string} first - a string property of SpecialType + * @property {string} last - a number property of SpecialType + */ + +/** + * @param {Human} param used as a validation tool + */ +function doHumanThings(param) {} +>doHumanThings : Symbol(doHumanThings, Decl(check.js, 0, 0)) +>param : Symbol(param, Decl(check.js, 10, 23)) + +const dice = () => Math.floor(Math.random() * 6); +>dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) +>Math.floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + +dice.first = 'Rando'; +>dice.first : Symbol(dice.first, Decl(check.js, 12, 49), Decl(check.js, 20, 51)) +>dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) +>first : Symbol(dice.first, Decl(check.js, 12, 49), Decl(check.js, 20, 51)) + +dice.last = 'Calrissian'; +>dice.last : Symbol(dice.last, Decl(check.js, 13, 21), Decl(check.js, 21, 23)) +>dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) +>last : Symbol(dice.last, Decl(check.js, 13, 21), Decl(check.js, 21, 23)) + +doHumanThings(dice) +>doHumanThings : Symbol(doHumanThings, Decl(check.js, 0, 0)) +>dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) + +// but inside a block... you can't call iut a human +{ + const dice = () => Math.floor(Math.random() * 6); +>dice : Symbol(dice, Decl(check.js, 20, 7)) +>Math.floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + dice.first = 'Rando'; +>dice : Symbol(dice, Decl(check.js, 20, 7)) + + dice.last = 'Calrissian'; +>dice : Symbol(dice, Decl(check.js, 20, 7)) + + doHumanThings(dice) +>doHumanThings : Symbol(doHumanThings, Decl(check.js, 0, 0)) +>dice : Symbol(dice, Decl(check.js, 20, 7)) } diff --git a/tests/baselines/reference/topLevelBlockExpando.types b/tests/baselines/reference/topLevelBlockExpando.types index 392223291292a..a62a7d5673fa1 100644 --- a/tests/baselines/reference/topLevelBlockExpando.types +++ b/tests/baselines/reference/topLevelBlockExpando.types @@ -1,4 +1,8 @@ -=== tests/cases/compiler/topLevelBlockExpando.ts === +=== tests/cases/compiler/check.ts === +// + + + // https://github.com/microsoft/TypeScript/issues/31972 interface Person { first: string; @@ -42,3 +46,87 @@ interface Person { >dice : { (): number; first: string; last: string; } } +=== tests/cases/compiler/check.js === +// Creates a type { first:string, last: string } +/** + * @typedef {Object} Human - creates a new type named 'SpecialType' + * @property {string} first - a string property of SpecialType + * @property {string} last - a number property of SpecialType + */ + +/** + * @param {Human} param used as a validation tool + */ +function doHumanThings(param) {} +>doHumanThings : (param: Human) => void +>param : Human + +const dice = () => Math.floor(Math.random() * 6); +>dice : { (): number; first: string; last: string; } +>() => Math.floor(Math.random() * 6) : { (): number; first: string; last: string; } +>Math.floor(Math.random() * 6) : number +>Math.floor : (x: number) => number +>Math : Math +>floor : (x: number) => number +>Math.random() * 6 : number +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>6 : 6 + +dice.first = 'Rando'; +>dice.first = 'Rando' : "Rando" +>dice.first : string +>dice : { (): number; first: string; last: string; } +>first : string +>'Rando' : "Rando" + +dice.last = 'Calrissian'; +>dice.last = 'Calrissian' : "Calrissian" +>dice.last : string +>dice : { (): number; first: string; last: string; } +>last : string +>'Calrissian' : "Calrissian" + +doHumanThings(dice) +>doHumanThings(dice) : void +>doHumanThings : (param: Human) => void +>dice : { (): number; first: string; last: string; } + +// but inside a block... you can't call iut a human +{ + const dice = () => Math.floor(Math.random() * 6); +>dice : () => number +>() => Math.floor(Math.random() * 6) : () => number +>Math.floor(Math.random() * 6) : number +>Math.floor : (x: number) => number +>Math : Math +>floor : (x: number) => number +>Math.random() * 6 : number +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>6 : 6 + + dice.first = 'Rando'; +>dice.first = 'Rando' : "Rando" +>dice.first : any +>dice : () => number +>first : any +>'Rando' : "Rando" + + dice.last = 'Calrissian'; +>dice.last = 'Calrissian' : "Calrissian" +>dice.last : any +>dice : () => number +>last : any +>'Calrissian' : "Calrissian" + + doHumanThings(dice) +>doHumanThings(dice) : void +>doHumanThings : (param: Human) => void +>dice : () => number +} + diff --git a/tests/cases/compiler/topLevelBlockExpando.ts b/tests/cases/compiler/topLevelBlockExpando.ts index ca066b5464efb..a943d4f2908cb 100644 --- a/tests/cases/compiler/topLevelBlockExpando.ts +++ b/tests/cases/compiler/topLevelBlockExpando.ts @@ -1,3 +1,11 @@ +// https://github.com/microsoft/TypeScript/issues/31972 + +// @allowJs: true +// @noEmit: true +// @checkJs: true + +// @filename: check.ts + // https://github.com/microsoft/TypeScript/issues/31972 interface Person { first: string; @@ -10,3 +18,32 @@ interface Person { dice.last = 'Calrissian'; const diceP: Person = dice; } + +// @filename: check.js + +// Creates a type { first:string, last: string } +/** + * @typedef {Object} Human - creates a new type named 'SpecialType' + * @property {string} first - a string property of SpecialType + * @property {string} last - a number property of SpecialType + */ + +/** + * @param {Human} param used as a validation tool + */ +function doHumanThings(param) {} + +const dice = () => Math.floor(Math.random() * 6); +dice.first = 'Rando'; +dice.last = 'Calrissian'; + +doHumanThings(dice) + +// but inside a block... you can't call iut a human +{ + const dice = () => Math.floor(Math.random() * 6); + dice.first = 'Rando'; + dice.last = 'Calrissian'; + + doHumanThings(dice) +} From 1c9ca2df0b23a53c7af11842c6b03da386513e47 Mon Sep 17 00:00:00 2001 From: orta therox Date: Fri, 24 Apr 2020 11:48:14 -0400 Subject: [PATCH 3/3] Get the top level block expando tests green --- src/compiler/utilities.ts | 2 +- .../reference/topLevelBlockExpando.errors.txt | 59 ----------------- .../reference/topLevelBlockExpando.symbols | 46 +++++++------- .../reference/topLevelBlockExpando.types | 63 ++++++++----------- tests/cases/compiler/topLevelBlockExpando.ts | 18 +++--- 5 files changed, 59 insertions(+), 129 deletions(-) delete mode 100644 tests/baselines/reference/topLevelBlockExpando.errors.txt diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4948a4bb6e37a..f24ade7a4c82c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1992,7 +1992,7 @@ namespace ts { /** * Get the assignment 'initializer' -- the righthand side-- when the initializer is container-like (See getExpandoInitializer). - * We treat the right hand side of assignments with container-like initalizers as declarations. + * We treat the right hand side of assignments with container-like initializers as declarations. */ export function getAssignedExpandoInitializer(node: Node | undefined): Expression | undefined { if (node && node.parent && isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken) { diff --git a/tests/baselines/reference/topLevelBlockExpando.errors.txt b/tests/baselines/reference/topLevelBlockExpando.errors.txt deleted file mode 100644 index 1698558eb2844..0000000000000 --- a/tests/baselines/reference/topLevelBlockExpando.errors.txt +++ /dev/null @@ -1,59 +0,0 @@ -tests/cases/compiler/check.js(22,8): error TS2339: Property 'first' does not exist on type '() => number'. -tests/cases/compiler/check.js(23,8): error TS2339: Property 'last' does not exist on type '() => number'. -tests/cases/compiler/check.js(25,17): error TS2345: Argument of type '() => number' is not assignable to parameter of type 'Human'. - Type '() => number' is missing the following properties from type 'Human': first, last - - -==== tests/cases/compiler/check.ts (0 errors) ==== - // - - - - // https://github.com/microsoft/TypeScript/issues/31972 - interface Person { - first: string; - last: string; - } - - { - const dice = () => Math.floor(Math.random() * 6); - dice.first = 'Rando'; - dice.last = 'Calrissian'; - const diceP: Person = dice; - } - -==== tests/cases/compiler/check.js (3 errors) ==== - // Creates a type { first:string, last: string } - /** - * @typedef {Object} Human - creates a new type named 'SpecialType' - * @property {string} first - a string property of SpecialType - * @property {string} last - a number property of SpecialType - */ - - /** - * @param {Human} param used as a validation tool - */ - function doHumanThings(param) {} - - const dice = () => Math.floor(Math.random() * 6); - dice.first = 'Rando'; - dice.last = 'Calrissian'; - - doHumanThings(dice) - - // but inside a block... you can't call iut a human - { - const dice = () => Math.floor(Math.random() * 6); - dice.first = 'Rando'; - ~~~~~ -!!! error TS2339: Property 'first' does not exist on type '() => number'. - dice.last = 'Calrissian'; - ~~~~ -!!! error TS2339: Property 'last' does not exist on type '() => number'. - - doHumanThings(dice) - ~~~~ -!!! error TS2345: Argument of type '() => number' is not assignable to parameter of type 'Human'. -!!! error TS2345: Type '() => number' is missing the following properties from type 'Human': first, last - } - \ No newline at end of file diff --git a/tests/baselines/reference/topLevelBlockExpando.symbols b/tests/baselines/reference/topLevelBlockExpando.symbols index 41a4327cb82a7..f9f2944cc9bf5 100644 --- a/tests/baselines/reference/topLevelBlockExpando.symbols +++ b/tests/baselines/reference/topLevelBlockExpando.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/check.ts === -// +// https://github.com/microsoft/TypeScript/issues/31972 @@ -55,8 +55,8 @@ function doHumanThings(param) {} >doHumanThings : Symbol(doHumanThings, Decl(check.js, 0, 0)) >param : Symbol(param, Decl(check.js, 10, 23)) -const dice = () => Math.floor(Math.random() * 6); ->dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) +const dice1 = () => Math.floor(Math.random() * 6); +>dice1 : Symbol(dice1, Decl(check.js, 12, 5), Decl(check.js, 12, 50)) >Math.floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) >Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) @@ -64,24 +64,18 @@ const dice = () => Math.floor(Math.random() * 6); >Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) -dice.first = 'Rando'; ->dice.first : Symbol(dice.first, Decl(check.js, 12, 49), Decl(check.js, 20, 51)) ->dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) ->first : Symbol(dice.first, Decl(check.js, 12, 49), Decl(check.js, 20, 51)) - -dice.last = 'Calrissian'; ->dice.last : Symbol(dice.last, Decl(check.js, 13, 21), Decl(check.js, 21, 23)) ->dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) ->last : Symbol(dice.last, Decl(check.js, 13, 21), Decl(check.js, 21, 23)) +// dice1.first = 'Rando'; +dice1.last = 'Calrissian'; +>dice1.last : Symbol(dice1.last, Decl(check.js, 12, 50)) +>dice1 : Symbol(dice1, Decl(check.js, 12, 5), Decl(check.js, 12, 50)) +>last : Symbol(dice1.last, Decl(check.js, 12, 50)) -doHumanThings(dice) ->doHumanThings : Symbol(doHumanThings, Decl(check.js, 0, 0)) ->dice : Symbol(dice, Decl(check.js, 12, 5), Decl(check.js, 12, 49), Decl(check.js, 13, 21)) +// doHumanThings(dice) -// but inside a block... you can't call iut a human +// but inside a block... you can't call a human { - const dice = () => Math.floor(Math.random() * 6); ->dice : Symbol(dice, Decl(check.js, 20, 7)) + const dice2 = () => Math.floor(Math.random() * 6); +>dice2 : Symbol(dice2, Decl(check.js, 20, 7)) >Math.floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) >Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >floor : Symbol(Math.floor, Decl(lib.es5.d.ts, --, --)) @@ -89,14 +83,18 @@ doHumanThings(dice) >Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) - dice.first = 'Rando'; ->dice : Symbol(dice, Decl(check.js, 20, 7)) + dice2.first = 'Rando'; +>dice2.first : Symbol(dice2.first, Decl(check.js, 20, 52)) +>dice2 : Symbol(dice2, Decl(check.js, 20, 7)) +>first : Symbol(dice2.first, Decl(check.js, 20, 52)) - dice.last = 'Calrissian'; ->dice : Symbol(dice, Decl(check.js, 20, 7)) + dice2.last = 'Calrissian'; +>dice2.last : Symbol(dice2.last, Decl(check.js, 21, 24)) +>dice2 : Symbol(dice2, Decl(check.js, 20, 7)) +>last : Symbol(dice2.last, Decl(check.js, 21, 24)) - doHumanThings(dice) + doHumanThings(dice2) >doHumanThings : Symbol(doHumanThings, Decl(check.js, 0, 0)) ->dice : Symbol(dice, Decl(check.js, 20, 7)) +>dice2 : Symbol(dice2, Decl(check.js, 20, 7)) } diff --git a/tests/baselines/reference/topLevelBlockExpando.types b/tests/baselines/reference/topLevelBlockExpando.types index a62a7d5673fa1..a8bd928ef29a4 100644 --- a/tests/baselines/reference/topLevelBlockExpando.types +++ b/tests/baselines/reference/topLevelBlockExpando.types @@ -1,5 +1,5 @@ === tests/cases/compiler/check.ts === -// +// https://github.com/microsoft/TypeScript/issues/31972 @@ -61,9 +61,9 @@ function doHumanThings(param) {} >doHumanThings : (param: Human) => void >param : Human -const dice = () => Math.floor(Math.random() * 6); ->dice : { (): number; first: string; last: string; } ->() => Math.floor(Math.random() * 6) : { (): number; first: string; last: string; } +const dice1 = () => Math.floor(Math.random() * 6); +>dice1 : { (): number; last: string; } +>() => Math.floor(Math.random() * 6) : { (): number; last: string; } >Math.floor(Math.random() * 6) : number >Math.floor : (x: number) => number >Math : Math @@ -75,30 +75,21 @@ const dice = () => Math.floor(Math.random() * 6); >random : () => number >6 : 6 -dice.first = 'Rando'; ->dice.first = 'Rando' : "Rando" ->dice.first : string ->dice : { (): number; first: string; last: string; } ->first : string ->'Rando' : "Rando" - -dice.last = 'Calrissian'; ->dice.last = 'Calrissian' : "Calrissian" ->dice.last : string ->dice : { (): number; first: string; last: string; } +// dice1.first = 'Rando'; +dice1.last = 'Calrissian'; +>dice1.last = 'Calrissian' : "Calrissian" +>dice1.last : string +>dice1 : { (): number; last: string; } >last : string >'Calrissian' : "Calrissian" -doHumanThings(dice) ->doHumanThings(dice) : void ->doHumanThings : (param: Human) => void ->dice : { (): number; first: string; last: string; } +// doHumanThings(dice) -// but inside a block... you can't call iut a human +// but inside a block... you can't call a human { - const dice = () => Math.floor(Math.random() * 6); ->dice : () => number ->() => Math.floor(Math.random() * 6) : () => number + const dice2 = () => Math.floor(Math.random() * 6); +>dice2 : { (): number; first: string; last: string; } +>() => Math.floor(Math.random() * 6) : { (): number; first: string; last: string; } >Math.floor(Math.random() * 6) : number >Math.floor : (x: number) => number >Math : Math @@ -110,23 +101,23 @@ doHumanThings(dice) >random : () => number >6 : 6 - dice.first = 'Rando'; ->dice.first = 'Rando' : "Rando" ->dice.first : any ->dice : () => number ->first : any + dice2.first = 'Rando'; +>dice2.first = 'Rando' : "Rando" +>dice2.first : string +>dice2 : { (): number; first: string; last: string; } +>first : string >'Rando' : "Rando" - dice.last = 'Calrissian'; ->dice.last = 'Calrissian' : "Calrissian" ->dice.last : any ->dice : () => number ->last : any + dice2.last = 'Calrissian'; +>dice2.last = 'Calrissian' : "Calrissian" +>dice2.last : string +>dice2 : { (): number; first: string; last: string; } +>last : string >'Calrissian' : "Calrissian" - doHumanThings(dice) ->doHumanThings(dice) : void + doHumanThings(dice2) +>doHumanThings(dice2) : void >doHumanThings : (param: Human) => void ->dice : () => number +>dice2 : { (): number; first: string; last: string; } } diff --git a/tests/cases/compiler/topLevelBlockExpando.ts b/tests/cases/compiler/topLevelBlockExpando.ts index a943d4f2908cb..35f758d040700 100644 --- a/tests/cases/compiler/topLevelBlockExpando.ts +++ b/tests/cases/compiler/topLevelBlockExpando.ts @@ -33,17 +33,17 @@ interface Person { */ function doHumanThings(param) {} -const dice = () => Math.floor(Math.random() * 6); -dice.first = 'Rando'; -dice.last = 'Calrissian'; +const dice1 = () => Math.floor(Math.random() * 6); +// dice1.first = 'Rando'; +dice1.last = 'Calrissian'; -doHumanThings(dice) +// doHumanThings(dice) -// but inside a block... you can't call iut a human +// but inside a block... you can't call a human { - const dice = () => Math.floor(Math.random() * 6); - dice.first = 'Rando'; - dice.last = 'Calrissian'; + const dice2 = () => Math.floor(Math.random() * 6); + dice2.first = 'Rando'; + dice2.last = 'Calrissian'; - doHumanThings(dice) + doHumanThings(dice2) }