Определение функции Typescript: возврат вложенного объекта с поиском ключей из массива значений - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть метод, который принимает в качестве входных данных объект, значения которого являются массивами строк; он возвращает объект, значения которого являются объектами с ключами, равными строковым значениям. Например,

myFunction({foo: ['a', 'b']}) // ==> {foo: {a: Widget, b: Widget}}

Я пытаюсь определить сигнатуру этой функции. Моя лучшая попытка:

declare function myFunction
  <Q extends string[], T extends {[key: string]: Q}>
  (keys: T) : {[key1 in keyof T]: {[key2 in T[key1][number]]: Widget}}

Это почти работает, за исключением того, что имена ключей вложенных объектов не выводятся. Первый пример возвращает:

{
    foo: {
        [x: string]: Widget;
    };
}

, тогда как я хочу, чтобы он возвратил

{
    foo: {
        a: Widget;
        b: Widget;
    };
}

Можно ли это сделать?

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

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

declare function myFunction
  <Q extends K[], T extends {[key: string]: Q}, K extends string>
  (keys: T): { [key1 in keyof T]: { [key2 in T[key1][number]]: Widget } }

Обратите внимание на Q extends K[], теперь мы говорим, что Q не string[], а K[], это означает, что TS сузит членов массива до более определенных c типов, чем строка.

0 голосов
/ 03 февраля 2020

Если ваш массив всегда содержит только "a" и "b", тогда вы можете определить тип строковых литералов объединения:

type MyUnionType = "a" | "b"

Затем определить переменную foo как MyUnionType[]. Результат:

declare function myFunction
  <Q extends MyUnionType[], T extends {[key: string]: Q}>
  (keys: T) : {[key1 in keyof T]: {[key2 in MyUnionType]: Widget}}

Должен работать:)


Но если ваш массив всегда состоит из разных строк, то такую ​​типизацию невозможно реализовать, потому что TypeScript только дизайн инструмент

...