Можно ли точно набрать _.invert в TypeScript? - PullRequest
3 голосов
/ 02 июня 2019

В lodash функция _.invert инвертирует ключи и значения объекта:

var object = { 'a': 'x', 'b': 'y', 'c': 'z' };

_.invert(object);
// => { 'x': 'a', 'y': 'b', 'z': 'c' }

Типы lodash в настоящее время объявляют это, чтобы всегда возвращать stringstring отображение:

_.invert(object);  // type is _.Dictionary<string>

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

const o = {
  a: 'x',
  b: 'y',
} as const;  // type is { readonly a: "x"; readonly b: "y"; }
_.invert(o);  // type is _.Dictionary<string>
              // but would ideally be { readonly x: "a", readonly y: "b" }

Можно ли получить такие точные наборы?Это объявление приближается:

declare function invert<
  K extends string | number | symbol,
  V extends string | number | symbol,
>(obj: Record<K, V>): {[k in V]: K};

invert(o);  // type is { x: "a" | "b"; y: "a" | "b"; }

Ключи верны, но значения являются объединением клавиш ввода, т. Е. Вы теряете специфику отображения.Можно ли получить этот идеал?

1 Ответ

3 голосов
/ 02 июня 2019

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

const o = {
    a: 'x',
    b: 'y',
} as const;

type AllValues<T extends Record<PropertyKey, PropertyKey>> = {
    [P in keyof T]: { key: P, value: T[P] }
}[keyof T]
type InvertResult<T extends Record<PropertyKey, PropertyKey>> = {
    [P in AllValues<T>['value']]: Extract<AllValues<T>, { value: P }>['key']
}
declare function invert<
    T extends Record<PropertyKey, PropertyKey>
>(obj: T): InvertResult<T>;

let s = invert(o);  // type is { x: "a"; y: "b"; }

AllValues сначала создает объединение, которое содержит все пары key, value (поэтому для вашего примера это будет { key: "a"; value: "x"; } | { key: "b"; value: "y"; }). В отображенном типе мы затем отображаем все типы value в объединении, и для каждого value мы извлекаем исходный key, используя Extract. Это будет работать хорошо, если нет повторяющихся значений (если есть повторяющиеся значения, мы получим объединение ключей, где бы значение не появлялось)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...