【问题标题】:Convert an interface to a tuple in typescript将接口转换为打字稿中的元组
【发布时间】:2019-04-03 03:09:33
【问题描述】:

我想将接口转换为键和值的元组。我想知道使用泛型是否可以做到这一点,但对语言特性知之甚少。

这是我想做的事情:

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

这可能吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我不确定你为什么想要这个,但是这里是......

    使用this answer 中的想法将映射类型转换为函数的交集,然后我们可以匹配不同的类型参数,我们可以定义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]
    

    另一种方法是在keyof 接口上使用UnionToIntersection,但我认为通过联合可能会带来更大的丢失接口成员顺序的风险。 (我相信我过去看到过工会失去秩序,虽然我刚才在操场上的测试中无法重现它。)在上面的解决方案中,已经确定交叉点是有序的,所以我们只依赖映射类型以保持顺序和IntersectionOfValues 中的推理过程以按顺序生成逆变候选并按顺序与它们相交。这仍然是依赖于实现的行为,但我认为它不太可能改变。

    【讨论】:

      猜你喜欢
      • 2021-07-24
      • 1970-01-01
      • 2018-10-10
      • 2021-06-03
      • 1970-01-01
      • 2020-12-27
      • 2018-06-14
      • 2021-12-19
      • 2018-11-10
      相关资源
      最近更新 更多