3

I'm trying to create a generic function which handles varies arrays of various types (that only share a few properties in common) and perform simple operations such as delete or add an item. How should the typing's look for such a function?

interface A {
    value: number;
    aasdsad?: number;
    abc: string;
}

interface B {
    value: number;
    asdsad1?: string;
}

export class Main {

    public getOneOfTheArrays(): A[] | B[] {
        return []; // return A[] or B[] depending on certain conditions
    }

    public getValue(index: number) {
        const arr: A[] | B[] = this.getOneOfTheArrays();
        const a = this.copy(arr[index]);
        a.value = 1234;
        arr.push(a); // <- typing's error here
    }

    public copy(obj: A | B): A | B {
        return Object.assign({}, obj);
    }

}

DEMO1 DEMO2

Error: arr.push(a) -> Argument of type 'A | B' is not assignable to parameter of type 'A & B'. Type 'B' is not assignable to type 'A & B'. Property 'abc' is missing in type 'B' but required in type 'A'.

Solution so far: (arr as typeof a[]).push(a);

1 Answer 1

3

You can not push A | B to A[] | B[] only when a is typeof B and arr typeof A[] because type B is missing abc attribute.

You ar able to push it when:

arr.push(a as A);
(arr as B[]).push(a as B);
(arr as B[]).push(a as A);

Sou you have to check i some way that a is B and arr is A[], and it that case apply some different logic.

Playground

Sign up to request clarification or add additional context in comments.

9 Comments

The closest we got so far: (arr as typeof a[]).push(a);
You will turn off compilation error, but what about case when you're trying to add B to A[]. You will have array of A where one of element has no attribute abc. So arr[42].abc will be undefined when TS will tell you thats string
That's true. But technically it can only be one type at a given time. I assume what I'm trying to achieve isn't possible?
As I understand you: its not possible only in case Array<A>.push(B) other 3 cases are fine.
What about with the use of generics and advanced types such as declare type OneOf<T> = T extends A ? A : B so it's clear to the developer that the function can only be called with one specific type at a time and that arr cannot be (A|B)[] at a given moment in time.
|

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.