I am struggling to make TypeScript happy in this particular case:
const t1 = new BehaviorSubject("test");
const t2 = new BehaviorSubject(["test2"]);
function transformString(subject:string):string
function transformString(subject:string[]):string[]
function transformString(subject:string|string[]):string|string[]{
if(Array.isArray(subject)){
return subject.map(t=>t.toUpperCase());
}
return subject.toUpperCase();
}
t1.pipe(map(transformString)); // Type error
t2.pipe(map(transformString));
t1.next(transformString(t1.value));
t2.next(transformString(t2.value));
The type error message I am getting is as follows:
Argument of type 'OperatorFunction<string[], string[]>' is not assignable to parameter of type 'OperatorFunction<string, string[]>'. Type 'string[]' is not assignable to type 'string'.ts(2345)
Adding the last two lines was a test to ensure the override was working correctly. Currently, my only workaround is specifying types at the map level:
t1.pipe(map<string,string>(transformString));
This seems redundant since we already know the type of t1. Initially, I intended to include the map operation inside a variable, but left it outside for now.
Edit:
As @Zerotwelve mentioned, the code above can function without using overloads. The real issue from my code in the minimal example lies elsewhere.
The problem arises when this code is utilized inside another function:
function t1F(): Observable<string> {
const t1 = new BehaviorSubject("test");
return t1.pipe(map(transformString));
}
TypeScript raises an error stating that
Type 'Observable<string | string[]>' is not assignable to type 'Observable<string>'. Type 'string | string[]' is not assignable to type 'string'.
Type 'string[]' is not assignable to type 'string'.