简体   繁体   English

是否可以有一个使用索引(类型或对象)的通用约束?

[英]Is it possible to have a generic constraint that uses an index(type or object)?

I am code-generating client models(Entities) as well as corresponding Primary Keys.我正在代码生成客户端模型(实体)以及相应的主键。

I would like to have a method signature whereby predicated on the Entity, the 2nd param should be its Primary Key only.我想要一个基于实体的方法签名,第二个参数应该只是它的主键。

The following use of type / class are not a requirement and may become interfaces or const for the map etc..以下使用类型 / class 不是必需的,可能成为 map 等的接口或常量。

What I have tried is:我试过的是:

export type ClassType<T> = new (...args: any[]) => T

export class CustomerPk {
  customerId: number;
}

export class VendorPk {
  vendorId: number;
}

export class Customer implements CustomerPk {
  customerId: number;
  name: string;
}

export class Vendor implements VendorPk{
  vendorId: number;
  name: string;
}

export type EntityType = Customer | Vendor;
export type EntityPk = CustomerPk | VendorPk;

export type entityToPkMap = {
  Customer: CustomerPk, Vendor: VendorPk
}

To consume like so:像这样消费:

  constructor() {   
    const myCust = this.GetData(Customer, new CustomerPk());
    const myVend = this.GetData(Vendor, new CustomerPk());  // I want this to guard at design time.
  }
  
  // Can I(how) structure the generated code 
  //  to be able to consume similar to the following?
  public GetData<T extends EntityType, K>(entity: ClassType<T>, primaryKey: K): T {
    // Get from store.
    throw new Error('Not Implemented');
  } 

I have tried variations of the following without finding what I am looking for:我尝试了以下变体,但没有找到我正在寻找的内容:

public GetData<T extends EntityType, K extends entityToPkMap[T]>(entity: ClassType<T>, primaryKey: K): T

Which errors with "Type 'T' cannot be used to index type 'entityToPkMap'." “类型'T'的哪些错误不能用于索引类型'entityToPkMap'。”

You could use conditional type to resolve primary key type:您可以使用条件类型来解析主键类型:

type PkMap<T> =
    T extends Customer ? CustomerPk :
    T extends Vendor ? VendorPk :
    never;

class Foo {
    constructor() {
        const myCust = this.GetData(Customer, new CustomerPk());
        const myVend = this.GetData(Vendor, new CustomerPk()); // expect error
    }

    public GetData<T>(entity: ClassType<T>, primaryKey: PkMap<T>): T {
        throw new Error('Not Implemented');
    }
}

Playground 操场

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

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