Когда вы используете типы кортежей в универсальных функциях, как вы можете «расширить» тип источника?
Допустим, мы хотим создать оператор отображения rxjs, который возвращает наблюдаемое значение (я) источника вместе с другим отображеннымзначение:
export function mapExtended<T, R>(mapping: (input: [T]) => R): OperatorFunction<[T], [T, R]>;
export function mapExtended<T1, T2, R>(mapping: (input: [T1, T2]) => R): OperatorFunction<[T1, T2], [T1, T2, R]>;
export function mapExtended<T1, T2, T3, R>(mapping: (input: [T1, T2, T3]) => R): OperatorFunction<[T1, T2, T3], [T1, T2, T3, R]>;
export function mapExtended<R>(mapping: (input: any) => R): OperatorFunction<any, {}> {
return (source$: Observable<any>) => source$.pipe(
map(input => {
const mappingResult = mapping(input);
return [...input, mappingResult];
}),
);
}
Кажется, что работает, но перегрузки не обнаружены должным образом.Тип возвращаемого значения для test
: Observable<[[number, number], number]>
вместо ожидаемого Observable<[number, number, number]>
:
const test = combineLatest(of(1), of(2)).pipe(
mapExtend(([s1, s2]) => s1 + s2),
);
Существует ли какая-либо проверка типа, чтобы сказать, что T
не может быть типом кортежа?
Я пытался выполнить то же самое с поддержкой отображаемых типов для кортежей, но безрезультатно, поскольку я не могу (или не знаю, как) «расширить» отображаемый тип:
type MapExtended2Input<T> = { [P in keyof T]: T[P] };
function mapExtended2<T extends any[], R>(mapping: (input: MapExtended2Input<T>) => R): OperatorFunction<MapExtended2Input<T>, [MapExtended2Input<T>, R]> {
return (source$: Observable<MapExtended2Input<T>>) => source$.pipe(
map(input => {
const mappingResult = mapping(input);
const result: [MapExtended2Input<T>, R] = [input, mappingResult];
return result;
}),
);
}
const test2 = combineLatest(of(1), of(2)).pipe(
mapExtended2(([s1, s2]) => s1 + s2),
);
Здесь тип возвращаемого значения также Observable<[[number, number], number]>
, что ожидается, но я не знаю, как «добавить» тип в сопоставленный тип кортежа.Пересечение не работает, или я делаю это неправильно.
РЕДАКТИРОВАТЬ:
Примером желаемой функциональности без rxjs будет:
Давайтескажем, мне нужна функция myFunc
, которая имеет 2 параметра общего типа:
- тип кортежа T с переменным числом элементов
- другой тип R
Результатом функции должен быть тип кортежа, содержащий все элементы типа кортежа T с добавленным к нему параметром типа R.
Например:
myFunc<T, R>(x, y); // Should return [T, R]
myFunc<[T1, T2], R>(x, y); // Should return [T1, T2, R]
myFunc<[T1, T2, T3], R>; // Should return [T1, T2, T3, R]
// ...