Преобразовать интерфейс в кортеж в машинописи - PullRequest
0 голосов
/ 30 октября 2018

Я хотел бы преобразовать интерфейс в набор ключей и значений. Мне было интересно, если бы это было возможно, используя дженерики, но я не знаю достаточно о языковых возможностях, чтобы сделать это.

Это то, что я хотел бы сделать:

interface Person {
    name: string,
    age: number
}

type Args = ToTuple<Person> // result would be ['name', string, 'age', number]

function DoSomethingWithArgs(...args: Args) {
    return (
        args[0] === 'name' &&
        typeof args[1] === 'string' &&
        args[2] === 'name' &&
        typeof args[3] === 'number'
    )
}

Возможно ли это?

1 Ответ

0 голосов
/ 31 октября 2018

Я не уверен, почему ты этого хочешь, но здесь идет ...

Используя идеи из этого ответа , чтобы преобразовать сопоставленный тип в пересечение функций, которые мы затем можем сопоставить с параметрами различных типов, мы можем определить ToTuple таким образом, чтобы он работал для фиксированного максимума. количество членов исходного интерфейса.

type IntersectionOfValues<T> =
  {[K in keyof T]: (p: T[K]) => void} extends
    {[n: string]: (p: infer I) => void} ? I : never;

type IntersectionOfFunctionsToType<F, T> =
    F extends {
        (na: infer NA, a: infer A): void;
        (nb: infer NB, b: infer B): void;
        (nc: infer NC, c: infer C): void;
    } ? [NA, A, NB, B, NC, C] :
    F extends {
        (na: infer NA, a: infer A): void;
        (nb: infer NB, b: infer B): void;
    } ? [NA, A, NB, B] :
    F extends {
        (na: infer NA, a: infer A): void
    } ? [NA, A] :
    never;

type ToTuple<T> = IntersectionOfFunctionsToType<
    IntersectionOfValues<{ [K in keyof T]: (k: K, v: T[K]) => void }>, T>;

interface Person {
    name: string,
    age: number
}

type Args = ToTuple<Person> // ['name', string, 'age', number]

Альтернативным подходом было бы использование UnionToIntersection на keyof интерфейса, но я считаю, что прохождение объединения может повлечь за собой больший риск потери порядка членов интерфейса. (Я полагаю, что в прошлом профсоюзы теряли порядок, хотя я не мог воспроизвести его в тестах на игровой площадке прямо сейчас.) В приведенном выше решении точно установлено, что перекрестки упорядочены, поэтому мы полагаемся только на сопоставленные типы для сохранения порядка и процесс вывода в IntersectionOfValues для генерации контравариантных кандидатов по порядку и их пересечения по порядку. Это все еще поведение, зависящее от реализации, но я думаю, что оно вряд ли изменится.

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