You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the above example I have a ConditionalType<T> that can be an object with value key only if we pass a number or string value, for all other cases the type should be the same as given type. Let's consider abstract class BaseClass<T> that takes one parameter in the constructor, which will be a type of { value: T } or T. We have created two more specific class ClassA and ClassB.
ClassA
ClassA extends BaseClass and adds restriction to its generic that it can be only sth that extends StringOrNuber type (string | number) so the BaseClass knows that T can be only a string or number so type of constructor parameter and test field should be { value: StringOrNumber }. This partly works. If I try to access this.test from ClassA then TS says the type of this.test is { value: number; } | { value: string; } what is good, but if I try to pass value that can be only a string or number wrapped in an object I am getting an error. What should not happen, I think (correct me if I am wrong)
Argument of type '{ value: StringOrNuber; }' is not assignable to parameter of type 'ConditionalType'
ClassB
ClassB extends BaseClass and adds restriction to its generic that it can be only sth that extends Record<PropertyKey, unknown> type (basically any object) so the BaseClass knows that T can NOT be a string or number so type of constructor parameter and test field should be T. This partly works. If I try to access this.test from ClassB then TS says the type of this.test is T what is good, but if I try to pass value that can be only an object I am getting an error. What should not happen, I think (correct me if I am wrong).
Argument of type 'T' is not assignable to parameter of type 'ConditionalType'.
Type 'Record<PropertyKey, unknown>' is not assignable to type 'ConditionalType'.
Then there is no any issues and types are inferred as expected.
To solve the above issue, I can use Union type and initialize test separately in ClassA and ClassB, but I would like to do it only once and do not repeat this operation in every class.
π Actual behavior
Class constructor parameters do not infer generic type to use it in ConditionalType
π Expected behavior
Class constructor parameters should infer generic type and use it in ConditionalType
The text was updated successfully, but these errors were encountered:
The constraint provided for ClassA is not applied to the conditional type in BaseClass, even they are literally the same. See discussions in #31096 and #32591.
The constraint provided for ClassA is not applied to the conditional type in BaseClass, even they are literally the same. See discussions in #31096 and #32591.
@whzx5byb So, this is impossible right now because of TypeScript limitations and this can be more like feature request than bug ?
Bug Report
π Search Terms
conditional types, generics
π Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about 4.6.4 (also beta channel)
β― Playground Link
Conditional types in constructor parameters cannot infer type from generics
π» Code
I want to create an abstract class that will store some common logic and type will be inferred based on the generic passed to this abstract class.
Simple example
Playground Link: Provided
In the above example I have a
ConditionalType<T>
that can be an object withvalue
key only if we pass anumber
orstring
value, for all other cases the type should be the same as given type. Let's considerabstract class BaseClass<T>
that takes one parameter in the constructor, which will be a type of{ value: T }
orT
. We have created two more specific classClassA
andClassB
.ClassA
ClassA
extendsBaseClass
and adds restriction to its generic that it can be only sth that extendsStringOrNuber
type (string | number
) so theBaseClass
knows thatT
can be only astring
ornumber
so type of constructor parameter andtest
field should be{ value: StringOrNumber }
. This partly works. If I try to accessthis.test
fromClassA
then TS says the type ofthis.test
is{ value: number; } | { value: string; }
what is good, but if I try to pass value that can be only astring
ornumber
wrapped in an object I am getting an error. What should not happen, I think (correct me if I am wrong)ClassB
ClassB
extendsBaseClass
and adds restriction to its generic that it can be only sth that extendsRecord<PropertyKey, unknown>
type (basically any object) so theBaseClass
knows thatT
can NOT be astring
ornumber
so type of constructor parameter andtest
field should beT
. This partly works. If I try to accessthis.test
fromClassB
then TS says the type ofthis.test
isT
what is good, but if I try to pass value that can be only an object I am getting an error. What should not happen, I think (correct me if I am wrong).If we use this
ConditionalType<T>
like that:Then there is no any issues and types are inferred as expected.
To solve the above issue, I can use Union type and initialize
test
separately inClassA
andClassB
, but I would like to do it only once and do not repeat this operation in every class.π Actual behavior
Class constructor parameters do not infer generic type to use it in
ConditionalType
π Expected behavior
Class constructor parameters should infer generic type and use it in
ConditionalType
The text was updated successfully, but these errors were encountered: