GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Property assignments in Typescript by sandersn · Pull Request #26368 · microsoft/TypeScript Conversation
Member
Allow JS-container (expando) property assignments in Typescript, but only for function declarations and function/arrow expressions used as initialisers of const variables. For example, now you can write the same code as you would in Javascript to make a callable object that also has properties: function borscht(ingredients: any[]) { // let's just skip straight to the ??? } borscht.and = 'burgers' Previously you need to merge a namespace: function borscht(ingredients: any[]) { // let's just skip straight to the ??? } namespace borscht { export var and = 'burgers' } Note that this only works in the value space. To specify a callable object with properties, you should still use object literal notation (or merge a namespace): declare const borscht = { (ingredients: any[]): Food and: string } Fixes #15868
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
But only for functions and constant variable declarations initialised with functions. This specifically excludes class declarations and class expressions, which differs from Javascript. That's because Typescript supports `static` properties, which are equivalent to property assignments to a class. Don't think it's right yet, but probably closer? The code is still fantastically ugly, but everything works the way it should. Also update baselines, even where it is ill-advised.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. getInitializerTypeFromSpecialDeclarations is only called once, so I just made the caller check for undefined. You should turn on Ignore Whitespace to read this review.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't want to create another wrapper/worker pair, but I couldn't come up with a better way to special-case the isJS check just for property assignments. Any ideas?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Nathan Shively-Sanders (sandersn)
requested review from
a user,
Daniel Rosenwasser (DanielRosenwasser) and
Ryan Cavanaugh (RyanCavanaugh)
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Member
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: In both places
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tests seem to pass without this line -- what's this protecting against?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FindAllReferences relies on this function, and perhaps other services do. Without this line, a few fourslash tests fail, pointing out that getSpecialPropertyAssignmentKind now recognizes any property assignment in TS files, even those that aren’t actually expando assignments. The left side of the or restores the old behavior for JS, and the right side adds to it for TS expando assignments. However, the right side isn’t tested. I need to add a case similar to the existing JS ones.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you briefly convince me that
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inside the containing
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsIt's not done yet. Specifically, in TS: Special property assignments are supposed to be declaration sites (but not all top-level assignments), and I think I got them to be. (But not sure). In JS: Special property assignments are supposed to be declaration sites (but not all top-level assignments), and I'm pretty sure ALL top-level assignments have been declaration sites for some time. This is incorrect, and probably means the predicate needs to be the same for both dialects. Now JS behaves the same as TS.
Deleted user (ghost)
approved these changes
Nathan Shively-Sanders (sandersn)
deleted the
property-assignments-in-ts
branch
|
There was an error while loading. Please reload this page.
|
This does not work when the property is a well-known symbol. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Kaleb Hornsby (@kaleb) that’s not part of the current design; it only applies to property accesses, not element accesses. And it doesn’t handle computed property names at all, even well-known symbols. Can you open a separate issue to track that? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Should TSC verify that every branch leads to an assignment in this case? type WarnUser = { (warning: string): void wasCalled: boolean } const warnUser: WarnUser = (warning: string) => { if (warnUser.wasCalled) { return } warnUser.wasCalled = true alert(warning) } if (Math.random() < .5) { warnUser.wasCalled = false } // No error |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Boris Cherny (@bcherny) Your example actually doesn't use control flow much, which means that we won't be able to issue a use-before-def error. Let's look at each use of
You can do two [interesting] things to change this:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Nathan Shively-Sanders (@sandersn) Thanks for the super detailed explanation of how the typechecker thinks about this example! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.