Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upGitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
Allow any key type as an index signature parameter type #26797
Conversation
@typescript-bot test this |
Heya @weswigham, I've started to run the extended test suite on this PR at 2c47d31. You can monitor the build here. It should now contribute to this PR's status checks. |
(2) typescript 2.9 not allow symbol to be used as index. microsoft/TypeScript#1863. Current there is a PR open to address this issue microsoft/TypeScript#26797
@RyanCavanaugh I see you marked this for TS 3.2. Is that still the plan? |
@spaceemotion My understanding of Partial is that it returns the properties as potentially undefined ie. {name?: string} whereas I want to be certain they are present and have a definite list of properties that preserve the original typing ie. go from: { to { Thank you for pointing out "Object" as a type to use for extending, it's obvious in retrospect, but sometimes a second set of eyes is what you need! For anyone reading this, here's a solution (as of TS 3.7.2) to obtain a new object with definite properties that are a subset of an existing generic type: function sanitiseData<T extends Object, U extends keyof T>(input: T, keysToKeep: U [ ]): {[key in U]: T[key] } {
let targetObj = {}
keysToKeep.forEach((key) => {
Object.assign(targetObj, {
[key]: input[key]
})
})
return targetObj as {[key in U]: T[key] }
} |
Thank you @ProdigySim , seems like Typescript natively supports this with the Pick keyword (I'm looking for positive properties to keep rather than negative properties to remove, which is what Omit does), but anyway thank you for reminding me of their existence |
What's the status of this PR? |
Still this comment. |
@weswigham re: #26797 (comment) Have you considered making |
I really care about this. Is there any way a less general approach to this can be made to work without breakage. For me, it's all about the symbol indexer signature. I just care about being able to say that some objects use symbols the same way they use string properties (this is standard JavaScript stuff). Just want to make symbols first class. Is there anything I can do to move this forward? I'm willing to commit to fixing this because right now it's a real pain for me to workaround as I happen to use symbols in a lot of places similarly to how you may have used just plain key/string properties today. |
I mean, since we added template literals and pattern templates this release, we'll probably revist it soonish since, symbols aside, types like interface AriaProps {
[index: `aria-${string}`]: string;
} have pretty compelling value (same as regex types as I was advocating for when I first worked on this, but more limited). |
If you get me proper symbol indexers this year, I will be forever grateful. |
The HTTP protocol example for templates is more convincing - great feature - sad that you couldn't push your proposal with regex patterns through. Is there a chance that regexp templates will be added in a later version? That would be awesome to generate code from JSON schema that recognizes pattern properties or type-safe compliance to (some) schema constraints. This would lift the usefulness of TypeScript to a whole new level. |
38ee04a
to
96bb1af
It was a long and painful merge (mapped type templates actually caused a ton of semantic conflicts, since I reused mapped type machinery in this PR), but now I can finally ask for @typescript-bot pack this Actual tests/extra implementation updates around pattern literals will be forthcoming, but a playground where the current state is visible should be useful~ |
Heya @weswigham, I've started to run the tarball bundle task on this PR at 96bb1af. You can monitor the build here. |
Hey @weswigham, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build. |
@weswigham alright, that solves it for me. If you're ever in Stockholm, let my buy you a |
Same if you find yourself in Melbourne, been waiting on this feature a long time. Thank you @weswigham |
@weswigham is this targeted for inclusion in the 4.2 release? @DanielRosenwasser will that be this year, or next year? |
How does interface Foo {
[x: "hello" | "world"]: number;
[x: "world" | "stuff"]: string;
} work with this? |
@leidegre the plan is for 4.2 to be late February, and we'd like this work to be brought in for 4.2. |
As-is, they resolve to concrete properties, and the overlapping property gets a combined type. As we stated at the last design meet we mentioned this topic, given our index signature behavior, it'd be nice if it had separate reading and writing types (which in theory might be implementable for these kinds of manufactured properties without modifying how existing props behave), however that is not what currently occurs (I think we currently always pick the writing type and produce an intersection). We could also layer on an error if we fell that kind of validation is important at declaration sites ("Index signatures only partially overlap and have incompatible types" or the like). You can always try it out in the playground associated with this PR to check the current behavior. |
This allows, eg,
symbol
:enums:
literal unions:
and generics:
as index signature parameter types.
Much of this functionality also exists in mapped types, except they had trouble shuffling around symbol information since there was no kind of index signature a symbol could map to. Unlike mapped types, however, since these are just index signatures, they can be added into any object type and in multiples.
Fixes #26470
Fixes #1863 (caveat: well-known symbols are not currently checked as part of a symbol index signature! Such checking should fall out from removing the concept of well-known symbols and using unique symbols instead)
Fixes #2491 in the original sense (rather than with mapped types).
Related: #28315