从tupple动态创建深层界面

时间:2019-02-20 20:33:45

标签: typescript

const deepProperty = ['example', 'hello', 'world'];

type MakeDeep<A extends string, B> = B;

type A = MakeDeep<typeof deepProperty, string>;

type B = {
  example: {
    hello: {
      world: string;
    },
  },
};

我正在寻找一种传递深层字符串和类型并从中创建接口的方法。

2 个答案:

答案 0 :(得分:1)

请注意,就“深度”而言,编译器的功能会有限制,但这希望对您有所帮助

const deepProperty: ["example", "hello", "world", "last"] = ['example', 'hello', 'world', "last"];


type MakeDeep<T extends any[]> = {
    [K in keyof T]: T[K] extends any
        ? Record<T[K], ((..._: T) => any) extends ((_: any, ..._1: infer TAIL) => any) ? MakeDeep<TAIL>[0] extends never ? string :  MakeDeep<TAIL>[0] : string>
        : never;
};


type Test = MakeDeep<typeof deepProperty>[0]


type TestInterface = Record<"example", Record<"hello", Record<"world", Record<"last", string>>>>


const TestAssignment: Test = {
    example: {
        hello: {
            world: {
                last: "STRING"
            }
        }
    }
} //passes

const TestAssignment2: Test = {
    example: {
        hello: {
            world: {
                last: 5
            }
        }
    }
} // fails

答案 1 :(得分:0)

我对递归类型确实不太好,但这是我的尝试。我从这两种类型开始,以迭代方式将数组转换为对象包装器。

type MakeDeep<T, A> =
    T extends Array<string> ? ((...x: T) => void) extends ((h, ...t: infer I) => void) ? { [key in T[0]]: Unwrap<I, A> } : {} : never;
type Unwrap<T, A> = T extends { length: 0 } ? A : MakeDeep<T, A>;

以下类型都是等效的:

const deepProperty: ['example', 'hello', 'world'] = ['example', 'hello', 'world' ];
type A = MakeDeep<typeof deepProperty, string>;

type B = {
  example: {
    hello: {
      world: string;
    },
  },
};