ken
ken

Reputation: 8993

Typing a property of an object that we know to be a string

I have a method in a class whose call signature is:

async where(
    prop: K & string,
    value: PropType<T, K> | [IComparisonOperator, PropType<T, K>],
    options: IDexieListOptions<T> = {}
  ) { ...}

The class's definition defines both T and K as:

class MyClass<T extends Model, K extends keyof T> { ... }

and the PropType type is simply this:

type PropType<TObj, TProp extends keyof TObj> = TObj[TProp]

In another method of the same class I try to use where like so:

  async since(datetime: epoch) {
    return this.where("lastUpdated", [">", datetime]);
  }

the lastUpdated property is a valid property of Model which <T> extends and of course it is also a "string" so it would appear to meet the signature for where() but instead I get this errror:

error msg

'"lastUpdated"' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string | number | symbol'.

Does anyone know how to get around this?


The Model class -- which I should have included to start with -- is defined as such:

export class Model {
  public id?: string;
  public lastUpdated?: number;
  public createdAt?: number;
}

I did wonder if the fact that lastUpdated is optional was a contributing factor but even making it required seems to make no difference.

Upvotes: 1

Views: 93

Answers (1)

iY1NQ
iY1NQ

Reputation: 2514

The problem is that your class define the second generic parameter K to be any subtype of keyof T but you are using a concrete subtype "lastUpdated" in the since() function when T isn't know yet. This isn't allowed as explained in detail here: https://stackoverflow.com/a/59363875/1628117

The solution of @jcalz in the above comments is an approach to solve this problem by letting the where function itself decide what a suitable subtype for keyof T is when invoked.

class MyClass<T extends Model> {

  async where<K extends keyof T>(
    prop: K, ...
  ) { }

  ...

}

Upvotes: 2

Related Questions