Typescipt типы и runtime значения — это два отдельных уровня, в основном написание typescript условий на основе значений не поддерживается, но есть решение.
Я хотел бы добиться следующего: Тип возврата функции изменяется в зависимости от значения, введенного в параметр функции.
function getUsers(withPagination: boolean): IUser[] | IPaginatedUsers {
// ...
return users;
}
Цель этой функции — возвращать пользователей из api, если параметр withPagination равен true, то она оборачивает массив пользователей в пагинацию, если false, то возвращается только массив пользователей (просто пример).
Проблема в том, что время выполнения показывает возвращаемое значение на основе переменной «withPagination», возвращаемое значение не является конкретным, но мы знаем, что оно будет, это может вызвать некоторую головную боль.
Одним из решений было бы указать возвращаемое значение обобщенно, но это не очень удобно и может быть испорчено. Другим решением является создание двух отдельных функций, что в данном случае может быть лучше, но это может привести к дублированию кода.
function getUsers(): IUser[] {
// ...
return users;
}
function getUserswithPagination(): IPaginatedUsers {
// ...
return users;
}
Если мы хотим сохранить все вместе и реализовать 2 или более различных возвратов безопасным для типов способом, то можно поступить следующим образом:
interface IUser {
name: string,
age: number,
}
interface IPaginated<T> {
data: T[],
meta: {
page: number,
limit: number,
totalPages: number
}
}
interface IResponseOptions {
withPagination: boolean
}
const DEFAULT_RESPONSE_OPTION = {
withPagination: true
}
type UserResultType<T extends IResponseOptions> = T extends {
withPagination: true
} ? IPaginated<IUser> : IUser[];
function getUsers<T extends IResponseOptions>(withPagination: T = DEFAULT_RESPONSE_OPTION as any): UserResultType<T> {
// fetch data..
return "something" as any as UserResultType<T>;
}
getUsers({withPagination: true}); // return IPaginated<IUser>
getUsers({withPagination: false}); // return IUser[];
getUsers(); // returns bsed on DEFAULT_RESPONSE_OPTION: IPaginated<IUser>