rxjs映射无法向带有重载的项目函数提示类型,如果未显式定义,则会导致类型错误



我很难弄清楚如何让typescript对这种情况感到满意:

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));

我收到的类型错误是:

类型为'OperatorFunction<string[],string[]>'不是可分配给'OperatorFunction<string,string[]>'。类型"string[]"不可分配给类型"string"。ts(2345(

我添加了最后两行,只是为了测试覆盖是否正常工作。目前,我找到的唯一解决方案是在地图级别搜索类型:

t1.pipe(map<string,string>(transformString));

但这是多余的,因为我们已经知道t1的类型了。此外,最初的计划是将地图包含在一个变量中,但我暂时将其放在了外部。

编辑:

正如@Zero12/所指出的,上面的代码可以在不使用重载的情况下工作。在上面的最小代码中,我没有从我的代码中发现真正的问题。

当它被用于另一个功能时,问题就来了:

function t1F(): Observable<string> {
const t1 = new BehaviorSubject("test");
return t1.pipe(map(transformString));
}

这里typescript抱怨

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'.

您可以尝试以下操作:

function transformString<T extends string | string[]>(subject: T): T {
if (Array.isArray(subject)) {
return subject.map((t) => t.toUpperCase()) as T;
}
return subject.toUpperCase() as T;
}
function t1F(): Observable<string> {
const t1 = new BehaviorSubject('test1');
return t1.pipe(map(transformString));
}
function t2F(): Observable<string[]> {
const t1 = new BehaviorSubject(['test2']);
return t1.pipe(map(transformString));
}

您可以这样做:

const t1 = new BehaviorSubject("test");
const t2 = new BehaviorSubject(["test2"]);
function transformString(subject:string|string[]):string|string[]{
if(Array.isArray(subject)){
return subject.map(t=>t.toUpperCase());
}
return subject.toUpperCase();
}
t1.pipe(map(transformString));
t2.pipe(map(transformString));

最新更新