Всем привет, основной вопрос в сабже.
Набросал условный пример того что хочу сделать:
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)