McFree
@McFree
JS, TS, C#

Можно ли передать нужный тип переменной в дженерик функции?

Есть проблема. Переменная которая получает из функции разные данные, соответсвенно не имеет идентичного типа в зависимости от данных.
Как можно передать нужный полученный из возвращаемых данных тип, чтобы передать этот тип как дженерик в следующую функцию?

Пример:
async getFormattedData(data: object): Promise<Type1 | Type2 | Type3> {
      const anyDataObject: Type1 | Type2 | Type3 = this.validateData(data);
      const result = this.formatDataByType<typeof anyDataType>(anyDataObject);
      return result;
}

formatDataByType<T extends UniversalType = Type1 | Type2 | Type3>(data: T): T {
      // какая-то работа в зависимости от разного набора данных в data объекте определяясь по типу
}


Можно ли как-то иметь возможность получить правильный тип T в функции formatDataByType или как можно реализовать подобную логику без копирования одной и той же логики на разные функции через определение по typeof?
  • Вопрос задан
  • 74 просмотра
Пригласить эксперта
Ответы на вопрос 1
Aetae
@Aetae Куратор тега TypeScript
Тлен
getFormattedData тоже должен быть дженерик и собсно его(дженерик) прокидывать в нижестоящие.

Типа того:
type Type1 = 1;
type Type2 = 2;
type Type3 = 3;
 
type ContainsType<T extends UniversalType = UniversalType> = {type: T};

type UniversalType = Type1 | Type2 | Type3;


class Cls {
  async getFormattedData<T extends UniversalType>(data: ContainsType<T>): Promise<T> {
        const anyDataObject = this.validateData(data);
        const result = this.formatDataByType(anyDataObject);
        return result;
  }

  validateData<T extends UniversalType = UniversalType>(data: ContainsType<T>): T {
    return data.type
  }

  formatDataByType<T extends UniversalType = UniversalType>(data: T): T {
    return data
  }

}
const foo = await new Cls().getFormattedData({type: 2}); // 2


Если ты явно чему-то пропиваешь тип который никак не зависит от входного дженерика:
const anyDataObject: Type1 | Type2 | Type3 = ...
то какбэ всё - приехали, ты сам указал, что тут именно такой тип(во всём его многообразии) и пофиг на входные данные. Ты можешь дальше сузить тип внутри метода:
if (anyDataObject === 2) {
  // тут anyDataObject для ts считается Type2
}
но это уже никак не повлияет на выходной тип.

В общем выводить типы можно только если они зависят от входных данных(которые в свою очередь получаются через дженерик), иначе откуда TS узнает, что там от чего зависит.
Если ты заранее даже приблизительно не знаешь, что придёт на вход, то и что пойдёт на выход ты ноже не знаешь, а не знаешь ты - не знает и, тем более, TS: там просто одни произвольные данные превратились в другие без использования логики. С тем же успехом можно попытаться вывести точный тип Math.random().
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы