-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mapped types enumerating keys in string
behave poorly
#22509
Comments
Ping @ahejlsberg |
string
behave poorlystring
behave poorly
That would be very cool! I guess it would be kind of like specifying a parameterised getter? (If that were a thing). interface Thing {
get <K extends string>(): <T>(base: T) => K extends keyof T ? T[K] : never;
} |
@jack-williams Sort of. It might mean that string index signatures would need to boil down to something similar to the following call signatures <K extends string>(x: K): *Type*;
<K extends string>(x: K, value: *Type*): void; But then what about numeric index signatures? You'd need a way to encode number-like strings: <K extends number | (numeric string)>(x: K): *Type*;
<K extends number | (numeric string)>(x: K, value: *Type*): void; |
@DanielRosenwasser Yes I guess you would want these to be equivalent: EDIT: The syntax I've picked is completely misleading as it just defines a method called interface Idx<T> {
[x: string]: T;
}
interface GetterSetter<T> {
get <K extends string>(): T
set <K extends string>(v: T): void;
} I'm afraid my understanding of numeric indexers probably has many holes. Am I correct in thinking that the stickiness with number-like strings mostly arises when you have named properties? E.g. interface NumGetSet<T> {
get <K extends number>(): T
set <K extends number>(v: T): void;
"10": number; // How do we detect that this is inconsistent?
} Although, I don't know if you want want to replace numeric indexers necessarily. Perhaps it could just be limited to types that extend |
This really is a request to add compiler support for ECMAScript proxy objects, i.e. compiler knowledge of the relationship between property access operations and the I do think this is entirely orthogonal to mapped types, and I think the current behavior of mapping over type |
@ahejlsberg I think proxies are a bit of a red herring here. For example, something like the following is fairly common I think? {
[K in string]?: K extends '_data' ? DataType : DefaultType
} It's like a type with an index signature but special properties don't have to be assignable to the index type. I agree this is somewhat useful for the get trap side of proxies. I believe exotic get behavior is more common than exotic call behavior so this may even be a reasonable starting point for "proxy support". I think I contest consistent, but I admit this is based on a surface-level understanding. I'll try to illustrate. Given the type
However, |
This doesn't seem to be a common request and I haven't seen other problems that would be solved by addressing this |
Keywords to find this later: generic index signature type parameters on index signature proxy @bterlson |
I have a use case now where this would be a helpful feature: type Item<T extends string> = {
id: T;
};
export type ItemMap = {
[id in string]: Item<id>;
};
const map: ItemMap = {};
const item = map['someid']; // type is Item<string> when it would be nice to be Item<'someid'> |
I would like a solution to this as well. I'm specifically interested in typing a Maybe this is a little contrived but you could assert an type IdMap<Keys extends string> = { [K in Keys]?: { id: K }} const map: IdMap<string> = {}
map.foo = { id: "foo" }
map.foo = { id: "bar" } // does NOT error as I believe it should If you're able to enumerate the possible keys (I'm not in my real use case) this does work as expected: const map: IdMap<"foo"|"bar"> = {}
map.foo = { id: "foo" }
map.foo = { id: "bar" } // DOES correctly error |
TypeScript Version: 2.8.0-dev20180308
Search Terms: mapped types
Code
Playground Link
Here I expect
string
to behave as if it were the union of all possible string literal types. The present semantics are identical to a string indexer. IMO if we don't want map typesK in string
to do anything interesting, then the syntax should be an error and we should require people to write the indexer.For what it's worth, ultimately I would love to type Allen's Apparatus for Method Extraction, roughly typed below:
I would probably work towards putting a constraint on T such that you get a red squiggle if you pass an object without the proper method to extract, but hopefully this serves as a useful example.
The text was updated successfully, but these errors were encountered: