Uh oh!
There was an error while loading. Please reload this page.
Keysof type operator - #10425
Conversation
01b0744 to
b156f71CompareAli Taheri Moghaddar (alitaheri)
commented
Aug 20, 2016
Also probably solves #7722. How would classes and namespaces work with this? ( if they should in the first place 😅 ) and how about index signatures? interfaceA{
foo: string;[property: string]: any;}what will be |
Wesley Wigham (weswigham)
commented
Aug 20, 2016
Ali Taheri Moghaddar (@alitaheri): |
| if (!type.resolvedBaseUnion) { | ||
| // Skip any essymbol members and remember to unescape the identifier before making a type from it | ||
| const memberTypes = map(filter(getPropertiesOfType(type.baseType), | ||
| symbol => !startsWith(symbol.name, "__@")), |
There was a problem hiding this comment.
Can you split this into intermediate variables?
Alex (wclr)
commented
Sep 1, 2016
When this going to landed? |
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). |
Alex (wclr)
commented
Sep 1, 2016
Daniel Rosenwasser (@DanielRosenwasser) it would be cool if another part for #1295 would be implemented soon |
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. |
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. |
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.
|
Remo H. Jansen (remojansen)
commented
Oct 24, 2016
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. |
Yehuda Katz (wycats)
commented
Oct 25, 2016
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: classX{constructor(privatename: string){}}letx=newX("Godfrey");x['name']// type checks, "Godfrey", type is string, as expectedx['nmae']// type checks, undefined, type is any, unexpectedIn other words, this trick conflates the elimination of privacy checks with a willingness to accept successful type-checking and We could use the classX{constructor(privatename: string){}}letx=newX("Godfrey");x['name']// type checks, value is "Godfrey", type is string, as expectedx['nmae']// type checks, value is undefined, type is any, unexpectedfunctionget<T,KextendskeysofT>(obj: T,key: K){returnobj[key];}letx=newX("Godfrey");get(x,'name')// type checks, "Godfrey", type is string (?), as expectedget(x,'nmae')// fails to type checkWhether 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 ( |
Aluan Haddad (aluanhaddad)
commented
Oct 30, 2016
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. |
Anders Hejlsberg (ahejlsberg)
commented
Nov 2, 2016
Closing as this has been superseded by #11929. |
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
typeof) -keysof. Used like so:A parameter or return type being a
keysoftype causes it to be contextually types as a string literal if need be. Akeysoftype resolves to a union of the string literal types of the keys of the given type when it is actually resolved (which it is resolved to for relationship checking). It isStringLike, and as such it has the apparent type of a string. It is effectively sugar for writing out the union type of all the keys of an object by hand, except it is also able to be generically instantiated.cc Daniel Rosenwasser (@DanielRosenwasser)