如何从多个属性动态构造类型?

时间:2019-03-19 15:30:16

标签: typescript types typescript-generics

我正在研究Typescript中的高级类型,到目前为止,我有一个type x,它带有一个通用参数props extends string。给定props的值为name | age | email,它将构造以下类型:

{
  name: "name",
  age: "age",
  email: "email"    
}

上述类型由以下类型定义生成:

type x<Property extends string> = { [K in Property]: K }

我也有上述类型的类型构造函数:

let x = <props extends string>(p: props): x<props> => (<x<props>>{[p]: p})

我可以通过简单地将字符串类型的属性传递给函数x来产生类型:

x("name") // Type is x<"name">

我想做的就是通过以下方式将多个属性传递给xx("name", "age", "email")产生类型x<"name" | "age" | "email">

我知道我可以通过重构方法x来实现这一点:

let x = <props extends string>(...p: props[]): x<props> => null! // Don't know how to implement this

但是我不知道如何从该输入构造一个具体对象,类似于(<x<props>>{[p]: p}),但是迭代传递给x的所有属性。

那么有没有一种方法可以遍历属性并动态构造类型?

1 个答案:

答案 0 :(得分:1)

您只需要遍历道具并将它们分配给新对象:

type x<Property extends string> = { [K in Property]: K }


let x = <props extends string>(...p: props[]): x<props> => {
    let result = {} as x<props>
    for (let k of p) {
        result[k] = k
    }
    return result;
} 

let a = x("name", "age") // Type is x<"name">
console.log(a);

没有一个魔术语法可以在单个表达式中生成该对象,因此我们使用类型断言向编译器说谎{}x<props>并在{{1 }}之后。有时需要类型断言,这是其中的一种,因为我们拥有编译器所没有的特殊信息(在接下来的两行中,我们将使for成为有效的{}的信息) )

或更简洁的单行版本:

x<props>