I have a function which I want it to return 2 type different types based on its argument props.
interface IPaginateParams {
perPage: number;
currentPage: number;
isFromStart?: boolean;
}
interface IWithPagination<Data, TParams extends IPaginateParams = IPaginateParams> {
data: Data;
pagination: IPagination<TParams>;
}
type IPagination<TParams> = TParams extends
| { currentPage: 1 }
| { isFromStart: true }
| { isLengthAware: true }
? ILengthAwarePagination
: IBasePagination;
interface IBasePagination {
currentPage: number;
perPage: number;
from: number;
to: number;
}
interface ILengthAwarePagination extends IBasePagination {
total: number;
lastPage: number;
}
function paginate<TData = any[], TParams extends IPaginateParams = IPaginateParams>(
options: TParams
): IWithPagination<TData, TParams>;
The idea is that if you pass currentPage: 1 or isFromStart: true, it should add 2 additional types to the pagination object.
The weird thing is that IWithPagination works as expected,
const data = {} as IWithPagination<any, {perPage: 2, currentPage: 1}>;
expectType<ILengthAwarePagination>(data.pagination);
But when I use the invocation, it always return the IBasePagination
const data = paginate({perPage: 2, currentPage: 1});
expectType<ILengthAwarePagination>(data.pagination) // fails
// or
const data = paginate({perPage: 2, currentPage: 2, isFromStart: true});
expectType<ILengthAwarePagination>(data.pagination) // fails