0

我正在代码生成客户端模型(实体)以及相应的主键。

我想要一个基于实体的方法签名,第二个参数应该只是它的主键。

以下类型/类的使用不是必需的,可能成为映射等的接口或常量。

我尝试过的是:

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
}

像这样消费:

  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');
  } 

我尝试了以下变体,但没有找到我正在寻找的内容:

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

“类型'T'的哪些错误不能用于索引类型'entityToPkMap'。”

4

1 回答 1

1

您可以使用条件类型来解析主键类型:

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');
    }
}

操场

于 2020-06-21T17:17:31.150 回答