bingo347
@bingo347
Crazy on performance...

Можно ли форсировать вывод типа для части дженерика?

Всем привет, основной вопрос в сабже.

Набросал условный пример того что хочу сделать:
type SomeComplicatedType = any; // здесь тоже сложный тип, но к сути вопроса он отношения не имеет
type BaseType = Record<string, SomeComplicatedType>;
type ResultType<T extends BaseType, K extends keyof T> = {t: T; k: K}; // тоже упростил для примера
function f<T extends BaseType, K extends keyof T>(key: K): ResultType<T, K> {
    /* ... */
    return {k: key, t: {} as T};
}
так вот, я хочу, чтоб T непосредственно задавался пользователем, а K выводился из аргумента и был бы конкретным литералом
type MyT = Record<string, number>;
const r = f<MyT>('test');
но тут дженерик ругается, что хочет 2 аргумента, а передан только 1

Итак, что пробовал:
1. если сделать такой вызов:const r = f('test');K прекрасно вычисляется в конкретный литеральный тип 'test', но T выводится как BaseType, что не устраивает
2. пробовал определить дефолтный тип:
function f<T extends BaseType, K extends keyof T = keyof T>(key: K): ResultType<T, K>

type MyT = Record<string, number>;
const r = f<MyT>('test');
так K скатывается ко всем ключам MyT, что тоже не подходит
3. была еще такая попытка:
function f<T extends BaseType, K extends keyof T = (infer KK extends keyof T ? KK : keyof T)>(key: K): ResultType<T, K>

type MyT = Record<string, number>;
const r = f<MyT>('test');
и хотя вроде это точно описывает, что я хочу, ts ругается на infer тут:
Объявления "infer" допустимы только в предложении "extends" условного типа.ts(1338)
  • Вопрос задан
  • 103 просмотра
Решения вопроса 1
Aetae
@Aetae Куратор тега TypeScript
Тлен
Нельзя, увы. На github'е много просьб это запилить, но пока(v3.8) надежды не много.
Если походить там по перекрёстным ссылкам, можно найти разные (некрасивые) workaround для конкретных случаев, но вот прямо как вы хотите - не получится.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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