Typescript, определяющий типы объекта, который может привести к результату - PullRequest
0 голосов
/ 09 декабря 2018

Если у меня есть объект как таковой

let obj = {
   property1:()=>{ return Date()} // eg it doesn't have to be a date
   property2:()=>{ return 1}   
}

Теперь я хочу преобразовать это в тип

{
   property1:Date,
   property2:number
}

Как бы я определил это в машинописи.Почти все, что я в итоге делаю, делает все правильно.

Я знаю свойства, поэтому знаю, что это что-то вроде

type Transform<T> = Record<keyof T,?>

как мне получить каждое отдельное свойство, которое нужно преобразовать так, чтобыконечный объект также может быть напечатан.

// Некоторым может потребоваться более точный пример

Допустим, это приложение реакции.

let dependencies = {user:UserContext}:{[key:string]:React.Context<any>}

Теперья могу преобразовать весь мой реагирующий контекст в фактические экземпляры внутри контекста, используя что-то вроде

Object.entries(contextObject).map(([key,context])=>{
   return {[key]:useContext(context)}
}).reduce((a,b)=>{
  return {...a,...b}
},{})

Этот объект будет преобразовывать все свойства.

Я принимаю объект конфигурации изсортирует и преобразует свойства, сохраняя все то же самое,

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

Doingэто не сложно, он печатается так, что на другом конце преобразования я знаю, в какой тип объекта был преобразован.

1 Ответ

0 голосов
/ 09 декабря 2018

Используйте встроенные типы Record и ReturnType:

/**
 * Apply the constraint of having functions as values.
 */
type Source = Record<string, () => any>;

/**
 * Map functions to their return types.
 */
type Transform<T extends Source> = {
    [Property in keyof T]: ReturnType<T[Property]>
}

/**
 * Make sure the argument fulfills the requirement.
 */
declare function transform<T extends Source>(source: T): Transform<T>;

Использование:

let source = {
   property1: () => { return new Date() },
   property2: () => { return 1 }   
}

/**
 * `property1` is an instance of `Date`, property2 is a `number`.
 */
const { property1, property2 } = transform(source);

Функцию transform можно реализовать следующим образом:

function transform<T extends Source>(source: T): Transform<T> {
    return Object
        .entries(source)
        .reduce(
          (cumulus, [key, value]) => Object.assign(cumulus, { [key]: value() }),
          Object.create({}),
        );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...