-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Unexpected any when using conditional type #59630
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
Reminds me of #59430, ultimately caused by #37348. I agree this looks weird, but itβs hard for me to see the intent when writing a conditional type like this where neither the source nor the target is generic. Whatβs happening now is similar to treating |
I was trying to reduce a rather complex type error in a real-world application. Chasing the weirdness led me here. |
For me, I don't care the use case. It's a bug! |
For consistency, every time you have something like this type V = { a: unknown };
type Type<T> = T extends V ? T['a'] : never; in the true branch, It's legitimate to do this even on non-type parameters! For example, you might have a library that needs to test the global type environment and light up certain features in post-ES2022 targets. You can also use it to induce weirdness on purpose, but that's a "succeeded at trying to fail" kind of situation. |
@RyanCavanaugh Why is the true branch type V = number // a given type
type Type<T> = T extends V ? T : never;// the true branch is V
type K = Type<string>// the true branch is T, also string. |
I see the point here. Is there a reason |
The example demonstrates why.
Because |
type V = { a: unknown };
type Type<T> = T extends V ? T['a'] : never; // in true branch, T is { a: any } In the example, the true branch type T = Type<{a:string}>. // in true branch, T is { a: string } In this call, the true branch T is
|
You can't just replace type V = { b: string };
type Foo<T extends { a: string }> = T extends V ? T['a'] : never; |
Should it be |
It can't be I think I'm done explaining generics from first principles in this thread; please use the Discord or Stack Overflow if you have further questions about why this works the way it does. |
This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
π Search Terms
conditional type any array
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?ts=5.6.0-beta#code/C4TwDgpgBAKhDOwoF4oDsCuBbARhATgNoC6UEAHsBGgCbxQCGaIJUA-OtnkcYZrgVIAudBABuBANxA
π» Code
π Actual behavior
Test
evaluates toany
π Expected behavior
Test
evaluates tonumber
Additional information about the issue
This seems to be the most minimal example that reproduces the issue.
It only happens when the type of the array being branched on is the same as the type of the array being indexed into in the first branch.
It does not happen when the condition is changed to
number extends any
It does not happen when both of the
number[]
s are changed into a generic, which is set tonumber[]
.It does not happen when the
any[]
is changed tounknown[]
.Changing the first branch to
true
causes the expression to evaluate totrue
, so Typescript is indeed evaluating the first branch.The text was updated successfully, but these errors were encountered: