I was playing with conditional types and stubbled upon this problem :
import { FormGroup, FormControl, AbstractControl } from '@angular/forms';
type Foo = FormGroup<{ title: FormControl<string> }>
type Bar = FormGroup<{ title2: FormControl<string>; }>;
type Baz = Foo | Bar extends FormGroup<infer U> ? 'ok ' : 'nok'; // NOK
// ^?
type Baz2 = Foo | Bar extends FormGroup ? 'ok ' : 'nok'; // OK
// ^?
Why would the presence of infer
change the return type here ?
CodePudding user response:
The compiler should normally be able to infer U
. I am not sure yet what the underlying issue is but I tracked it down to the following:
The inference fails because FormGroup
contains methods which have a conditional in their return type.
Without the conditional, inference works fine.
type Foo = FormGroup<{ title: string }>
type Bar = FormGroup<{ title2: string }>;
export declare class FormGroup<TControl = any> {
fn1(arg: TControl): TControl
// fn2(arg: TControl): 0 extends TControl ? true : false
}
type Baz = Foo | Bar extends FormGroup<infer U> ? true : false;
// ^? type Baz = true
As soon as we introduce the conditional in a return type, the inference breaks.
type Foo = FormGroup<{ title: string }>
type Bar = FormGroup<{ title2: string }>;
export declare class FormGroup<TControl = any> {
fn1(arg: TControl): TControl
fn2(arg: TControl): 0 extends TControl ? true : false
}
type Baz = Foo | Bar extends FormGroup<infer U> ? true : false;
// ^? type Baz = false
I may do some further investigation into this issue.
possibly related:
CodePudding user response:
The infer
keyword is used to narrow the type of an expression.
In the first case, the type of the expression Foo | Bar
is the union of the types Foo
and Bar
.
The first type is FormGroup<{ title: FormControl<string> }>
while the second one is FormGroup<{ title2: FormControl<string> }>
.
Since these types aren't the same, their union is not equal to FormGroup<infer U>
.
But this is not true in the second case, because both Foo
and Bar
are a subtype of FormGroup
, for this the second case results in ok