Сделайте объект самосознающим его форму без явного набора текста - PullRequest
0 голосов
/ 22 апреля 2020

Рассмотрим следующие два типа:

type CoolFunction = (c: CoolType) => any

type CoolType = {
    [key: string]: CoolType | CoolFunction
}

// can be nested many times
const example: CoolType = {
    foo: {
        bar: {},
        dog: (c) => c.foo
    },
    baz: (c) => c.foo.bar
}

Возможно ли построить функцию, которая принимает значение CoolType, которое автоматически предоставит тип аргумента, переданного в CoolFunction, без необходимости предоставить аргумент типа для функции?

function doCoolStuff<T extends CoolType>(myCoolObj: T) {
    // recursively search for and call all CoolFunctions in myCoolObj with myCoolObj as param
}

doCoolStuff({
    someProperty: {
        foo: {},
    },
    somethingElse: {
        // the type of c should automatically be inferred to be the object we're currently creating
        test: (c) => c.someProperty.foo
    }
})

Я предполагаю, что CoolType придется принять некоторые параметры типа, а затем передать их рекурсивно внутрь, но мои попытки до сих пор всегда заканчиваются на типе будучи any или never. Пример:

type CoolFunction<C extends CoolType<any, any>> = (c: C) => any;

// an attempt to provide the entire object shape,
// as well as the subtree of the property we're currently typing
type CoolType<
  Tree extends CoolType<any, any>,
  Subtree extends CoolType<any, any>
> = {
  [K in keyof Subtree]: Subtree[K] extends CoolFunction<Tree>
    ? CoolFunction<Tree>
    : Subtree[K] extends CoolType<any, any>
    ? CoolType<Tree, Subtree[K]>
    : never
};

function doCoolStuff<C extends CoolType<any, any>>(myCoolObj: C) {
  // recursively search for and call all CoolFunctions in myCoolObj with myCoolObj as param
}

doCoolStuff({
  foo: {
    bar: {}
  },
  // c: any
  baz: c => console.log(c.foo.bar)
});

Есть указатели? Возможно ли то, что я пытаюсь сделать?

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