-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
boolean in recursive generic inferred as any (string and number work correctly) #29477
Comments
The problem stems from the fact that // type N = Predicate<number> | ((value: number) => Predicate<number>)
type N = SpecValue<(typeof data)["number1"]>;
// type B = Predicate<false> | ((value: false) => Predicate<false>) | Predicate<true> | ((value: true) => Predicate<true>)
type B = SpecValue<(typeof data)["boolean1"]>; This definition of export type SpecValue<INPUT> =
[INPUT] extends [object]
? {[key in keyof INPUT]: SpecValue<INPUT[key]>}
: Predicate<INPUT> | ((value: INPUT) => Predicate<INPUT>);
// type B = Predicate<boolean> | ((value: boolean) => Predicate<boolean>)
type B = SpecValue<(typeof data)["boolean1"]>; Tag for searching purpose: distributive conditional type trouble |
Yes, it looks like it works for that small example. But I still have trouble with my real code... I'm not really sure what Why can't I use it the other way around?
|
If you have a conditional type
I use You can apply the same trick that; seems to work for me: export type SpecFunction<INPUT, ROOTINPUT = any> = [INPUT] extends [ReadonlyArray<infer U>]
? (value: INPUT) => ReadonlyArray<SpecArray<U, ROOTINPUT>>
: [INPUT] extends [object]
? (value: INPUT) => SpecObject<INPUT, ROOTINPUT>
: (value: INPUT) => SpecArray<INPUT, ROOTINPUT>;
export type SpecObject<INPUT, ROOTINPUT = any> = Partial<{[key in keyof INPUT]: SpecValue<INPUT[key], ROOTINPUT>}>
export type SpecValue<INPUT, ROOTINPUT = any> = [INPUT] extends [ReadonlyArray<any>]
? SpecArray<INPUT, ROOTINPUT> | SpecFunction<INPUT, ROOTINPUT>
: [INPUT] extends [object]
? SpecArray<INPUT, ROOTINPUT> | SpecFunction<INPUT, ROOTINPUT> | SpecObject<INPUT, ROOTINPUT>
: SpecArray<INPUT, ROOTINPUT> | SpecFunction<INPUT, ROOTINPUT>; |
Yes, this works great! Thank you! I didn't apply this trick to the Arrays. Guess I have to read some more about those distributive types. But you can only use |
TypeScript Version: 3.2.4 (also happened with 3.2.2, no information about prior versions)
Search Terms:
generic(s), boolean, infer(red), any
Code
I've removed as much of the type definitions as possible while still getting the error.
In the test code you can see, that the error happens somewhere in the recursive part.
I've included the same 2 cases for
string
andnumber
, too (where they work). the only issue comes with typeboolean
.Expected behavior:
boolean
should behave exactly the same asstring
andnumber
Actual behavior:
boolean
behaves specialPlayground Link:
http://www.typescriptlang.org/play/#src=declare%20function%20spected%3CINPUT%2C%20SPEC%20extends%20SpecValue%3CINPUT%3E%20%3D%20SpecValue%3CINPUT%3E%3E(spec%3A%20SPEC%2C%20input%3A%20INPUT)%3A%20any%3B%0D%0A%0D%0Aexport%20type%20Predicate%3CINPUT%3E%20%3D%20(value%3A%20INPUT)%20%3D%3E%20boolean%0D%0A%0D%0Aexport%20type%20SpecValue%3CINPUT%3E%20%3D%0D%0A%20%20%20%20INPUT%20extends%20%7B%5Bkey%3A%20string%5D%3A%20any%7D%0D%0A%20%20%20%20%20%20%20%20%3F%20%7B%5Bkey%20in%20keyof%20INPUT%5D%3A%20SpecValue%3CINPUT%5Bkey%5D%3E%7D%0D%0A%20%20%20%20%20%20%20%20%3A%20Predicate%3CINPUT%3E%20%7C%20((value%3A%20INPUT)%20%3D%3E%20Predicate%3CINPUT%3E)%3B%0D%0A%20%20%20%20%20%20%20%20%0D%0A%2F%2F%20TEST%20CODE%20%231%3A%0D%0Aconst%20data%20%3D%20%7B%0D%0A%20%20%20%20str1%3A%20%22%22%2C%0D%0A%20%20%20%20str2%3A%20%22%22%2C%0D%0A%20%20%20%20number1%3A%200%2C%0D%0A%20%20%20%20number2%3A%200%2C%0D%0A%20%20%20%20boolean1%3A%20true%2C%0D%0A%20%20%20%20boolean2%3A%20true%0D%0A%7D%0D%0A%0D%0Aconst%20res%20%3D%20spected%3Ctypeof%20data%3E(%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20str1%3A%20(value)%20%3D%3E%20false%2C%0D%0A%20%20%20%20%20%20%20%20str2%3A%20(value)%20%3D%3E%20(value)%20%3D%3E%20false%2C%0D%0A%20%20%20%20%20%20%20%20number1%3A%20(value)%20%3D%3E%20false%2C%0D%0A%20%20%20%20%20%20%20%20number2%3A%20(value)%20%3D%3E%20(value)%20%3D%3E%20false%2C%0D%0A%20%20%20%20%20%20%20%20boolean1%3A%20(value)%20%3D%3E%20true%2C%20%2F%2F%20ERROR%3A%20value%20is%20of%20type%20any%0D%0A%20%20%20%20%20%20%20%20boolean2%3A%20(value)%20%3D%3E%20(value)%20%3D%3E%20true%20%2F%2F%20ERROR%3A%20value%20is%20of%20type%20any%20(both)%0D%0A%20%20%20%20%7D%2C%0D%0A%20%20%20%20data%0D%0A)%3B%0D%0A%0D%0A%2F%2F%20TEST%20CODE%20%232%3A%0D%0Aspected((value)%20%3D%3E%20false%2C%20%22%22)%3B%0D%0Aspected((value)%20%3D%3E%20(value)%20%3D%3E%20false%2C%20%22%22)%3B%0D%0Aspected((value)%20%3D%3E%20false%2C%200)%3B%0D%0Aspected((value)%20%3D%3E%20(value)%20%3D%3E%20false%2C%200)%3B%0D%0Aspected((value)%20%3D%3E%20false%2C%20true)%3B%0D%0Aspected((value)%20%3D%3E%20(value)%20%3D%3E%20false%2C%20true)%3B
Related Issues:
none yet?
The text was updated successfully, but these errors were encountered: