-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
Let us intersect the type of a function argument based on the value of another argument #41233
Comments
Please respect the issue templates for bug reports and feature requests. :-) This will make the work for the TypeScript team much easier and they can focus on improving the language, instead of deciphering GitHub issues. Fundamentally a duplicate of #27808. |
Hi @marcin-serwin sorry about not following the issue template. Please accept my apology. I think my issue is slightly different than #27808 as because this is about dynamic literal types. Let me leave this as a comment there. Thanks. |
There already is |
@MartinJohns this has nothing to do with #27808. Your problem is that your You want type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
type ExtractField<T> = T extends { field: infer F } ? F : never;
class User<U> {
private _user: Partial<U> = {};
public set<K extends keyof U>(
key: K,
val: ExtractField<UnionToIntersection<U extends infer OneCase ? (K extends keyof OneCase ? {field : OneCase[K]} : never) : never>>,
) : void {
this._user[key] = val as any;
}
} Converting the union to an intersection achieves the correct variance here. Alternatively you could directly inline that function declaration to get the appropriate variance (UnionToInsersection is just a bit of a hack). |
I'm saying that #27808 would allow this to be typed in a sound way. |
I am loathe to suggest it, but this is the one legitimate use case for Union to Intersection conversion: https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type The "proper" fix would be #14520 |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Here is a basic
User
class:And a basic
Employee
interface:Now, consider the following implementation:
The above script yields the following error which is expected.
Now take a look at the following implementation:
The above script does not yield any error and it is also expected, as long as
10
is assignable toname
orrole
.To make it more clear, let's take a look at the following script:
The above script yields the following error which is also expected.
Now, what I want to achieve is,
10
should not be allowed to be stored as a value ofname
at any mean.For this, I need to make some changes to my code something similar to the followings:
But as long as there is nothing like
valueof key
, this cannot be achieved dynamically.For testing, if you replace
U[ K ]
byU[ "name" ]
, you will see10
is no longer allowed anymore at any form.Many programmers solved similar problems by applying
T[ keyof T ]
which I think is not applicable to this case.Thanks in advance.
Playground
The text was updated successfully, but these errors were encountered: