Typescript定义对象上可以产生结果的类型

时间:2018-12-09 14:39:57

标签: javascript typescript types interface

如果我有这样的物体

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,?>

如何获取每个要转换的属性,以便最终对象也可以键入。

//有些人可能需要更可靠的例子

让我们说这是一个React应用。

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}
},{})

此对象将转换为所有属性。

我接受各种配置对象并转换属性,使所有内容保持不变,

可以是任何东西,可以将某些参数转换为db表, 将依赖项转换为要添加到类的类,而无需实际创建实例

这样做并不难,只需键入它,以便在转换的另一端,我知道对象的类型已转换为什么类型。

1 个答案:

答案 0 :(得分:3)

使用内置的RecordReturnType类型:

/**
 * 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({}),
        );
}