Цель состоит в том, чтобы создать функцию Pipe, которая ограничивает Piping менее производным типом, чем первоначально заданный (Contravariance), используя как можно меньше деклараций типа.
Кажется, что можно создать такой Pipe. Сценарий ниже.
interface Task<A> {
(): Promise<A>;
}
declare const initialValue: Task<boolean>;
declare const firstLine: (ma: Task<boolean>) => Task<void>;
declare const secondLine: (ma: Task<void>) => Task<void>; // working
declare const secondLineProblem: () => Task<void>; // compilation error
type PipedFunc<ExpectedType, AtualType, Result> = ((
a: AtualType
) => Result) extends (b: any) => any
? AtualType extends ExpectedType
? (b: AtualType) => Result
: [
"Function does not match the expected signature: ",
(b: ExpectedType) => Result
]
: never;
type Pipe = {
<A>(a: A): A;
<A, B>(a: A, ab: (a: A) => B): B;
<A, B, BArg, C>(a: A, ab: (a: A) => B, bc: PipedFunc<B, BArg, C>): C;
<A, B, BArg, C, CArg, D>(a: A, ab: (a: A) => B, bc: PipedFunc<B, BArg, C>, cd: PipedFunc<C, CArg, D>): D;
};
export const pipe: Pipe = function(
a: unknown,
ab?: Function,
bc?: Function,
cd?: Function,
): unknown {
switch (arguments.length) {
case 1:
return a;
case 2:
return ab!(a);
case 3:
return bc!(ab!(a));
case 4:
return cd!(bc!(ab!(a)));
}
return;
};
let task01 = pipe(initialValue, firstLine, secondLine, secondLine);
let task02 = pipe(initialValue, firstLine, secondLine, secondLineProblem); // Expected compilation Error
// ↑
// Compilation Error - Argument of type '() => Task<void>' is not assignable to parameter of type
//'["Function does not match the expected signature: ", (b: Task<void>) => Task<void>]'.ts(2345)
Но этот подход делает необходимым использование o Декларации типа.
let sum00 = pipe(10, firstValue => firstValue + 1, (secondValue: number) => secondValue); // works
Цель состоит в том, чтобы найти подход, который выводит тип для аргумента секунд ниже , Без использования объявления типов.
let sum00 = pipe(10, firstValue => firstValue + 1, secondValue => secondValue); // does not work
// ↑
// Compilation Error - Parameter 'value' implicitly has an 'any' type.ts(7006)
Возможно ли это? Он думал об использовании какого-либо условного типа для вывода Типа SecondValue
, но не было возможности найти какой-то правильный пример.
Существуют ли способы придумать это решение в TypeScript?