简体   繁体   English

将接口转换为打字稿中的元组

[英]Convert an interface to a tuple in typescript

I would like to convert an interface into a tuple of keys and values. 我想将接口转换为键和值的元组。 I was wondering if this would be possible using generics, but don't know enough about the language features to do this. 我想知道使用泛型是否有可能,但是对语言功能了解得不够多。

This is the kind of thing I would like to do: 这是我想做的事情:

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'
    )
}

Is this possible? 这可能吗?

I'm unsure why you want this, but here goes... 我不确定为什么要这样,但是这里...

Using ideas from this answer to convert a mapped type to an intersection of functions that we can then match against different type parameters, we can define ToTuple in a way that will work for a fixed maximum number of members of the original interface. 使用此答案中的构想,将映射的类型转换为函数的交集,然后我们可以将其与不同的类型参数进行匹配,我们可以以适用于固定数量的原始接口成员的方式定义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]

An alternative approach would be to use UnionToIntersection on keyof the interface, but I believe that going through a union may carry a greater risk of losing the order of the members of the interface. 另一种方法是使用UnionToIntersectionkeyof接口,但我相信,经历工会可携带失去接口的成员的顺序的风险更大。 (I believe I've seen unions lose order in the past, though I couldn't reproduce it in tests in the playground just now.) In the solution above, it's well-established that intersections are ordered, so we are only relying on the mapped types to preserve order and the inference process in IntersectionOfValues to generate the contravariant candidates in order and intersect them in order. (我相信我曾经见过工会失去秩序,尽管我现在无法在操场上的测试中重现它。)在上面的解决方案中,确定交叉点是有序的,所以我们仅依靠映射的类型以保留顺序,并在IntersectionOfValues进行推理过程以按顺序生成反变候选并按顺序相交。 This is still implementation-dependent behavior, but I think it's unlikely to change. 这仍然是依赖于实现的行为,但是我认为这不太可能改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM