繁体   English   中英

打字稿映射类型或类型数组

[英]Typescript Mapped Types or Arrays of Types

我正在尝试将Typescript映射类型用于简单的查询API。 让我提供一个简化的示例:

interface IRoot {
  user: IUser,
  trips: Array<ITrip>
}

interface IUser {
  name: string
}

interface ITrip {
  prop: string
}

现在,我可以构造一个查询:

class Query<T, K extends keyof T> {
  constructor(
    private rootType: T, 
    private subQueries?: {[P in K]?: Query<T[P], any> }) { }
}

这样可以很好地访问用户,但无法解析行程的数组类型:

new Query(({} as IRoot), {
  user: new Query(({} as IUser), ... /* This is a query on User and is accepted here */, 
  trips: new Query(({} as ITrip), ... /* This is a query on Trip and TS will complain, since T[P] is Array<ITrip> */
})

有什么想法可以扩展{[P in K]?: Query<T[P], any> }以接受T[P]或者如果T[P]是一个Array,则为该数组的类型吗?

一个想法是创建一个IQuery接口并创建两个实现,一个实现简单的属性,一个实现数组的属性。 Query将实现IQuery,而ArrayQuery将实现IQuery。 IQuery接口将需要具有使用T的方法或字段,以确保ArrayQuery<T>Query<T>在结构上不兼容。

interface IQuery<T> {
    // We need this method since the compiler checks structural compatibility we need to make implementations of IQuery<T> and IQuery<T[]> incompatible.
    getRootType(): T;
}
class Query<T, K extends keyof T> implements IQuery<T>{
    constructor(
      private rootType: T, 
      private subQueries?: {[P in K]?: IQuery<T[P]> }) { 

      }
    getRootType(): T {
          return this.rootType;
    }
}

class ArrayQuery<T, K extends keyof T> implements IQuery<T[]>{
    constructor(private rootType: T,private  subQueries?: {[P in K]?: Query<T[P], any> }) { 

    }
    getRootType(): T[]{
        return [this.rootType];
    }
}

new Query(({} as IRoot), {
    user: new Query(({} as IUser)), 
    trips: new ArrayQuery(({} as ITrip)) 
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM