Тип TypeScript, который копирует другой тип объекта, но изменяет тип свойств на основе их исходного условия типа

#typescript

Вопрос:

Мне нужен тип TypeScript, который копирует другой тип объекта, но изменяет тип свойств на основе их исходного состояния типа. А также сделайте это для всех вложенных и глубоко вложенных свойств.

Например, тип DateToStrings<T> , который превратил бы все свойства типа Date в свойства типа string . Это будет выглядеть так:

Если у меня есть класс:

 class Milk {
  brandName: string,
  prince: number,
  dealExpiredAt: Date,
  properties: {
    expirationDetails: {
      expiredAt: Date
    }
  }
}
 

Тип DateToStrings<Milk> будет:

 {
  brandName: string,
  price: number,
  dealExpiredAt: string,
  properties: {
    expirationDetails: {
      expiredAt: string
    }
  }
}
 

Был бы очень признателен за помощь, поскольку у меня на самом деле нет указаний, как к нему подойти, какие-либо советы или известные типы / пакеты типов, которые делают что-то подобное?

Комментарии:

1. class Milk: { недопустимый синтаксис. У вас есть class или type ?

2. @AlekseyL. Спасибо исправлено

Ответ №1:

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

 type DateToStrings<T> = {
    [K in keyof T]: T[K] extends Date
    ? string
    : T[K] extends Array<infer I>
    ? Array<DateToStrings<I>>
    : T[K] extends object
    ? DateToStrings<T[K]>
    : T[K]
}

type MilkTransformed = DateToStrings<Milk>

const foo: MilkTransformed = {
    brandName: 'string',
    prince: 123,
    dealExpiredAt: 'Date',
    properties: {
        expirationDetails: {
            // Expected error: Type 'Date' is not assignable to type 'string'
            expiredAt: new Date
        }
    }
}
 

Игровая площадка

Комментарии:

1. Здесь у вас есть один крайний случай, когда свойство является кортежем foo: [Date, Date] 🙂 Пожалуйста, не рассматривайте этот комментарий как критику ответа. У вас есть мой голос

2. Да, также функции, принимающие даты в качестве параметров или возвращающие дату / объект или массив с датой