rxjs map 无法通过重载提示类型到项目函数,如果没有显式定义会导致类型错误
rxjs map cannot hint type to project function with overload, causing type errors if not explicitly defiend
我很难弄清楚如何让打字稿对这种情况感到满意:
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));
我收到的类型错误是这样的:
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)
我添加了最后两行只是为了测试覆盖是否正常工作并且确实如此。目前,我找到的唯一解决方案是在地图级别寻找类型:
t1.pipe(map<string,string>(transformString));
但这变得多余了,因为我们已经知道 t1 的类型了。另外,最初的计划是将地图包含到一个变量中,但我暂时把它放在外面了。
编辑:
正如@Zerotwelve 所指出的,上面的代码可以在不使用重载的情况下工作。在上面的最小代码中,我没有从我的代码中发现真正的问题。
在另一个函数中使用时出现问题:
function t1F(): Observable<string> {
const t1 = new BehaviorSubject("test");
return t1.pipe(map(transformString));
}
这里打字稿抱怨
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'.
你可以这样做:
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));
您可以尝试以下操作:
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
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));
我收到的类型错误是这样的:
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)
我添加了最后两行只是为了测试覆盖是否正常工作并且确实如此。目前,我找到的唯一解决方案是在地图级别寻找类型:
t1.pipe(map<string,string>(transformString));
但这变得多余了,因为我们已经知道 t1 的类型了。另外,最初的计划是将地图包含到一个变量中,但我暂时把它放在外面了。
编辑:
正如@Zerotwelve 所指出的,上面的代码可以在不使用重载的情况下工作。在上面的最小代码中,我没有从我的代码中发现真正的问题。
在另一个函数中使用时出现问题:
function t1F(): Observable<string> {
const t1 = new BehaviorSubject("test");
return t1.pipe(map(transformString));
}
这里打字稿抱怨
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'.
你可以这样做:
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));
您可以尝试以下操作:
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));
}