-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Incorrect substitution on index access with generic key type on generic mapped type with key remapping #47794
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
Comments
We consider an indexed access type So, the issue here isn't that the example should type check, but rather that the error message is wrong. We should be reporting that type |
You are the judge on this, but I don't think we have to prevent the simple cases simply because complex cases are not supported. In this bug's case, we don't need to do a reverse mapping, as instantiating For more context, here is an example where reverse mapping would be necessary : type Mapped2<K extends string> = { [P in K as `get${P}`]: { a: P } };
function f2<K extends string>(obj: Mapped2<K>, key: `get${Exclude<K, 'A'>}`) {
const x: { a: Exclude<K, 'A'> } = obj[key]; // This is obviously correct, but needs reverse mapping to be type checked correctly
} If you'd prefer, I might be able to implement a reverse mapping that works in most cases, even if it won't be complete. |
It looks like my issue is a more complex version of the same thing. I'm not TypeScript superstar, so I'm not completely sure though, checking here before posting another issue. Here's what my code does: type Type = "a" | "b";
type Stuff = {
type: Type;
};
const Factory = {
a (_arg: string): Stuff { return { type: "a" } },
b (_arg: number): Stuff { return { type: "b" } }
}
type FactoryParameter = {
[type in Type]: Parameters<typeof Factory[type]>[0];
}
function foo<T extends Type>(type: T, param: FactoryParameter[T]): Stuff {
return Factory[type](param);
}
const v1 = foo("a", "hello");
const v2 = foo("b", 12); The issue is in function "foo()". It builds fine with I get the error below.
Is this the same bug? Is there something I'm missing here? |
@j3k0 your code is incorrect, as it would allow foo<'a' | 'b'>('a', 12) |
@LANGERGabrielle you are right, thanks. Though my use case doesn't really allow your pattern, my actual "foo" function needs to use the Factory, but do many other things with the thing it builds: it can't just return the Factory unfortunately. All I can do is build the "Stuff" outside the function (makes the things less nice to use... but OK) For the record, my issue is more like those: #13995 #25879 - TypeScript can't force a type to be singleton (yet... I hope). Thanks again. |
I still think it's a shame that key remapping is unusable with generics. I had the impression that what I was proposing was sound. |
Bug Report
As soon as this bug is approved I can open the PR with my fix.
This seems somewhat related to #44115
🔎 Search Terms
mapped remapping
🕗 Version & Regression Information
⏯ Playground Link
Playground link for ^4.4
Playground link for ^4.1
💻 Code
🙁 Actual behavior
When resolving the type of
foo[`get${t}`]
, Typescript substitutesRemappedT
with`get${T}`
.foo[`get${t}`]
ends up resolving to`get${T}`
.🙂 Expected behavior
Typescript should resolve
foo[`get${t}`]
with the typeT
.The text was updated successfully, but these errors were encountered: