0

I have the following piece of code

// Address and User are two classes, bothe of which have an id
type Q = Address | User

// This works just fine 
async function c<EntityType extends Q>(ids: Q["id"][]) {
}

// This gives me the error described bellow
async function c<EntityType extends Q>(ids: EntityType["id"][]) {
}

When I in vscode hover over ids in the first function I get (parameter) ids: number[] (Which is expected as Q.id is a number) but if I hover over ids in the second function I get ids: EntityType["id"][]

This is leading to errors downstream... Why is this happening and how can I gix this?


Edit: Adding the aforementioned errors:

In the function I am using the line

  const e = await em.findBy(entityClass, { id: In(ids) });

And typescript complains:

Argument of type '{ id: FindOperator<any>; }' is not assignable to parameter of type 'FindOptionsWhere<EntityType> | FindOptionsWhere<EntityType>[]'.
  Types of property 'id' are incompatible.
    Type 'FindOperator<any>' is not assignable to type 'FindOptionsWhereProperty<NonNullable<EntityType["id"]>>'

On {id: In(ids)} (entityClass is of type EntityType)

2
  • 1
    could you elaborate on "errors downstream" Commented Oct 11, 2022 at 20:15
  • I don't see a problem with this tsplay.dev/ND2yjW What exactly is the error you have? Commented Oct 11, 2022 at 20:19

1 Answer 1

0

Alright, after searching around, I found that you were using typeorm. Instead of having Q be a union of the classes you define. You should make it an interface in which classes can implement, which I've renamed EntityType based on your generic. The resulting code would be:

interface EntityType {
    id: number;
}

class Address implements EntityType {
    id: number;
    // your code
}

class User implements EntityType {
    id: number;
    // your code
}

async function b<T extends EntityType>(entityClass: EntityTarget<T>, em: EntityManager, ids: number[]): Promise<T[]> {
    const e = await em.findBy(entityClass as EntityTarget<EntityType>, { id: In(ids) });
    return e as T[];
}
Sign up to request clarification or add additional context in comments.

3 Comments

Will this also work if I do: async function b<T extends EntityType>(entityClass: EntityTarget<T>, em: EntityManager, ids: number[]): Promise<T[]> {
hmm not sure why typeorms type declarations seem to complain when the input is generic. However, it should be safe to cast it within the function so typescript can stop complaining. I'll update my answer accordingly
When I do this it does unfortunately not remove the error I am getting...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.