Inconsistent iif type checking behavior in typescript 5.0.2
moniuch opened this issue · 3 comments
moniuch commented
Describe the bug
Given the below snippet
const source$ = from([{ firstName: 'Brian', lastName: 'Smith' }, null]);
const err = new Error('my error');
const final$ = source$.pipe(
switchMap((o) =>
iif(
() => !o,
throwError(() => err),
of(`${o.firstName} ${o.lastName}`)
)
)
);
I'm getting different results depending on IDE, and I am not sure I'm using the operators correctly
(rxjs 7.8.0 and - typescript 5.0.2 in both cases)
VSCode (complains about o
being possibly null
)
In both cases final$
is reported as Observable<string>
Expected behavior
Given that we catch the null condition in iif
the typescript should not complain in the truthy execution branch
Reproduction code
import { of, switchMap, from, throwError, iif } from 'rxjs';
const source$ = from([{ firstName: 'Brian', lastName: 'Smith' }, null]);
const err = new Error('my error');
const final$ = source$.pipe(
switchMap((o) =>
iif(
() => !o,
throwError(() => err),
of(`${o.firstName} ${o.lastName}`)
)
)
);
### Reproduction URL
_No response_
### Version
7.8.0
### Environment
_No response_
### Additional context
_No response_
demensky commented
There are no errors on stackblitz because TypeScript does not run in strict mode on it by default:
I recommend simplifying to this:
import { of, switchMap, from } from 'rxjs';
const source$ = from([{ firstName: 'Brian', lastName: 'Smith' }, null]);
const final$ = source$.pipe(
switchMap((o) => {
if (!o) {
throw new Error('my error');
}
return of(`${o.firstName} ${o.lastName}`);
})
);
Or even to this:
import { from, map } from 'rxjs';
const source$ = from([{ firstName: 'Brian', lastName: 'Smith' }, null]);
const final$ = source$.pipe(
map((o) => {
if (!o) {
throw new Error('my error');
}
return `${o.firstName} ${o.lastName}`;
})
);
moniuch commented
Ah ok, thanks for this strict: true
lesson, I wasn't aware of it. Closing then. Sorry for the noise.
demensky commented
The most appropriate code for your version:
const source$ = from([{firstName: 'Brian', lastName: 'Smith'}, null]);
const err = new Error('my error');
const final$ = source$.pipe(
switchMap((o) =>
!o
? throwError(() => err)
: of(`${o.firstName} ${o.lastName}`),
)
);