тип рекурсивного объекта отображения в машинописи - PullRequest
1 голос
/ 18 апреля 2020

Я создаю объект сопоставления в машинописном тексте, который безопасен для типов.

Я могу получить эту работу на глубине одного уровня с этой игровой площадкой и этим кодом

enum TransformerActions { 
  Delete = 'delete',
}

type TransformerMap<S> = { 
  [P in keyof S]?: S[P] extends object
    ? ((s: S) => any) | TransformerActions
  : S[P];
};

interface Name { 
  forename?: string;
  surname?: string;
}

type Person = { currentName: Name, previousNames: Name[] }

const personTransformer1: TransformerMap<Person> = {
  currentName: TransformerActions.Delete
}

const personTransformer2: TransformerMap<Person> = {
  currentName: (s) => s.currentName.forename + ' ' + s.currentName.surname
}

Но если бы я хотел сделать это рекурсивным типом, чтобы каждый вложенный ключ мог иметь преобразования, я не могу получить синтаксис, попробовал это:

type TransformerMap<S> = { 
  [P in keyof S]?: S[P] extends object
    ? TransformerMap<S[P]>
  : S[P] | ((s: S) => any) | TransformerActions;
};

Но это не работает.

Как я могу создать рекурсивный тип таким образом.

1 Ответ

0 голосов
/ 18 апреля 2020

Если я правильно понял, что насчёт этого?

enum TransformerActions {
  Delete = 'delete',
}

type TransformerFunc<T> = (src: T) => Partial<T>

type TransformerMap<S> = {
  [P in keyof S]?: S[P] | TransformerFunc<S[P]> | TransformerActions | TransformerMap<S[P]>;
};

interface Name {
  forename?: string;
  surname?: string;
}

type Person = { currentName: Name, previousNames: Name[], child: Person }

const personTransformer1: TransformerMap<Person> = {
  currentName: TransformerActions.Delete
}

const personTransformer2: TransformerMap<Person> = {
  currentName: {
    forename: TransformerActions.Delete
  },
  child: {
    currentName: (child) => {
      return {
        forename: `${child.forename?.toUpperCase()} ${child.surname?.toUpperCase}`,
        surname: TransformerActions.Delete
      }
    },
    child: TransformerActions.Delete
  }
}

Посмотрите на пример детская площадка .

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