Условный тип второго аргумента функции - PullRequest
0 голосов
/ 01 июля 2019

У меня есть следующая функция:

function doSomething(param1: string, param2: string) {
  return param1 + param2;
}

также у меня есть тип на основе json со структурой, похожей на эту:

a1: {
  b1: 'something1',
  b2: 'something2',
  b3: 'something3'
},
a2: {
  c1: 'something4',
  c2: 'something5'
}

...etc

Я хочу, чтобы n-й аргумент упомянутой функции был литералом n-х глубоких элементов, поэтому, если первый аргумент 'a1', второй должен быть 'b1' | 'b2' | 'b3', а если первый аргумент 'a2', второй должен быть 'c1' | 'c2'.

Для первого аргумента я сделал простой тип keyof typeof data, который прекрасно работает:

// data is imported json
type FirstArg = keyof typeof data;

На секунду я попробовал общий тип, подобный этому, но безуспешно:

type SecondArg<T extends FirstArg> = keyof typeof data[T];

Есть ли шанс сделать это?

1 Ответ

2 голосов
/ 01 июля 2019

Вы не можете сделать это для любого количества аргументов, вы можете определить перегрузки вплоть до определенной глубины:

const data = {
    a1: {
        b1: 'something1',
        b2: 'something2',
        b3: 'something3'
    },
    a2: {
        c1: 'something4',
        c2: 'something5'
    }
}
type DataType = typeof data;
function doSomething<K extends keyof DataType, K2 extends keyof DataType[K]>(p1: K, p2: K2, p3: keyof DataType[K][K2]): string
function doSomething<K extends keyof DataType>(p1: K, p2: keyof DataType[K]): string
function doSomething(p1: keyof DataType): string
function doSomething(...keys: PropertyKey[]) {
    return keys.join('.');
}

doSomething("a1", "b1")
doSomething("a1", "c2") // err
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...