Можно ли создать псевдоним, когда дженерик относится к определенному типу?

Мне нужен тип, который принимает обобщенный объект, который расширяет объект функций и "вложенных" функций и "возвращает" объект, в котором каждая функция имеет измененную сигнатуру функции.

Так это

{ foo: (a) => (b) => ({}), nested: { bar: (a) => (b) => ({}) } }

становится этим

{ foo: (a) => ({}), nested: { bar: (a) => ({}) } }

Я пытался ввести это так:

type Convertor<
  T extends { [key: string]: NestedMap<Function> | Function }
> = { [P in keyof T]: Converting<T[P]> }

Это не работает, так как Converting<T[P]> должно происходить только тогда, когда это функция. т.е. для foo и nested.bar, но не для nested, так как это объект.

Как это правильно напечатать?


person Highmastdon    schedule 15.01.2018    source источник


Ответы (1)


Пока не появятся условные типы, вы можете использовать безумное решение из https://github.com/Microsoft/TypeScript/issues/12424#issuecomment-356685955

type False = '0';
type True = '1';
type If<C extends True | False, Then, Else> = { '0': Else, '1': Then }[C];

type Diff<T extends string, U extends string> = (
    { [P in T]: P } & { [P in U]: never } & { [x: string]: never }
)[T];

type X<T> = Diff<keyof T, keyof Object>

type Is<T, U> = (Record<X<T & U>, False> & Record<any, True>)[Diff<X<T>, X<U>>]

type DeepFun<T> = {
    [P in keyof T]: If<Is<Function & T[P], Function>, ()=>{}, DeepFun<T[P]>>
}

type MyType = { foo: (a:any) => (b:any) => ({}), nested: { bar: (a:any) => (b:any) => ({}) } }
type NewType = DeepFun<MyType>;
var d:NewType; // type is {foo: ()=>{}, nested: {bar: ()=>{}}}
person cevek    schedule 15.01.2018