如何通过参数值在命名空间中指定通用类型

时间:2019-05-31 20:56:38

标签: typescript

我有一个从数据库中提取一行的函数。

function row<T>(table:string, id:number):Promise<T|null>
{
   //For simplicity's sake
   return await Db(`SELECT * FROM ${table} WHERE id = ${id}`)
}

还有名称空间中表的类型定义

export namespace Table
{
   export type office = {
      id:number
      location:string
   }

   export type person = {
      id:number
      name:string
      office:number
   }
}

当前,我通过传递的泛型类型运行它,

const person = row<Table.person>('person', 1)

这将为person提供Table.person的类型,但是如何使用参数的字符串值使其通用呢?

我希望可以实现这样的目标,以便它可以通过'table'字符串参数从'Table'命名空间中提取类型定义。

function row(table:string, id:number):Promise<Table[table]|null>

1 个答案:

答案 0 :(得分:0)

TypeScript名称空间对我们可以执行的类型操作有限制。如果我们尝试对名称空间进行类型操作,则编译器将告诉我们不能将名称空间用作类型或值。

这是一种解决方法,可以手动将Table命名空间转换为TableMap类型,以便我们可以对其进行类型操作。

具有比我更多的TypeScript经验的人也许可以通过生成Tables类型而不是手动创建它来改善此解决方法。

namespace Table {
  export type office = {
    id: number
    location: string
  }
  export type person = {
    id: number
    name: string
    office: number
  }
}

type TableMap = {
  'office': Table.office,
  'person': Table.person,
};

type TableKey = keyof TableMap;

function row<Key extends TableKey>(table: Key, id: number): Promise<TableMap[Key] | null> {
  return null;
}

const result = row('person', 1)

这里是in the playground,表明result的类型为Promise<Table.person>