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 — Keysof type operator by weswigham · Pull Request #10425 · microsoft/TypeScript Conversation
Member
Fixes half of #1295. (Honestly, that issue is like proposals for three separate but interoperating features) The remaining parts of #1295 are what I call a "type access expression" - a mirror of element access expressions, but for types (quite literally the same logic) - and altering index resolution logic to, rather than using unions to check for index signature compatibility, be able to use a union of string literals to create a union of the types of those members. The part that this PR addresses is an operator for finding all of the keys of an arbitrary type. This PR adds a new "type operator" (akin to interface Item<T> { owner: Person; id: number; contents: T } let x: keysof Item<any>; x = "id"; // valid x = "owner" // valid x = "content" // error! "content" not assignable to keysof Item<any> interface HelloWorld { hello: any; world: any; } function check<K extends keysof HelloWorld>(key: K): K{ return key; } // 'y' has type '"hello"' let y = check("hello"); check("hullo"); // error! "hullo" not assignable to keysof HelloWorld A parameter or return type being a
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Wesley Wigham (weswigham)
force-pushed
the
keysof-type-operator
branch
from
01b0744 to
b156f71
Compare
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.
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 split this into intermediate variables?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
|
There was an error while loading. Please reload this page.
|
Renamed in favour of (@whitecolor) We need to discuss this at a design meeting. There are small details that can make all the difference (such as what to do with index signatures). |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Daniel Rosenwasser (@DanielRosenwasser) it would be cool if another part for #1295 would be implemented soon |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
I think this is a big step forward for the type system. The question I have, and sorry if this has already been answered, is this: What is the enumeration algorithm used?
On the one hand, it could be very surprising to not get the property keys of super class properties, especially as subclassing becomes more and more fashionable. On the other, it would be equally surprising if it behaved differently from Personally, I would prefer it to only return enumerable own properties, but I almost never create class hierarchies in TypeScript. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Aluan Haddad (@aluanhaddad) Problem is that enumerable own properties aren't encoded in the type system and there's not really a straightforward way we've thought of to add it. Nathan Shively-Sanders (@sandersn) ran into similar issues with the object rest & spread operators. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Daniel Rosenwasser (@DanielRosenwasser) thank you for clarifying. It makes a lot of sense that the language does not track own properties because statically modelling the flexibility of JavaScript's composition mechanisms would seem to preclude doing so. Perhaps if this operator walks the prototype chain a different name would be appropriate.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I created #11813 because I was not aware of this. I have closed it but it can still be used as a real world use case for the need of this operator. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Aluan Haddad (@aluanhaddad) I can understand why you expect That said, I'd find it unfortunate if this very useful operator was restricted to enumerable-own properties. Here's an example scenario I ran into today that got me thinking about this feature again: creating a hard-fail version of the index-for-friendly-access trick: class X { constructor(private name: string) {} } let x = new X("Godfrey"); x['name'] // type checks, "Godfrey", type is string, as expected x['nmae'] // type checks, undefined, type is any, unexpected In other words, this trick conflates the elimination of privacy checks with a willingness to accept successful type-checking and We could use the class X { constructor(private name: string) {} } let x = new X("Godfrey"); x['name'] // type checks, value is "Godfrey", type is string, as expected x['nmae'] // type checks, value is undefined, type is any, unexpected function get<T, K extends keysof T>(obj: T, key: K) { return obj[key]; } let x = new X("Godfrey"); get(x, 'name') // type checks, "Godfrey", type is string (?), as expected get(x, 'nmae') // fails to type check Whether this works or not depends on whether Regardless of those details, this illustrates that there may be valid use-cases for My own perspective is that This might also argue for a few flavors of Finally, I also wonder whether not encoding enumerable/own in the type system will be practical in the long-term, especially considering the soon-to-be-included object-spread ( |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Yehuda Katz (@wycats) I think you're points about overall usefulness outweigh my arguments about consistency with existing features. While I don't use classes particularly often I do find the object-spread example very compelling. In light of that feature, requiring ownness would kill a lot of the usefulness even in scenarios involving simple object literals. Also if manifest mixin support is ever added to ECMAScript, restricting it to enumerable own properties would also be very unfortunate. I am convinced. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Closing as this has been superseded by #11929. |
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.