Typescript inherited interface and literal string type key error

347 views Asked by At

I have 3 interfaces (A, B, and C below) that all extend from a common interface (Common below). I also have a container type that contains arrays of these 3 interfaces (Container below).

I want to grab one of the arrays and pluck a common property from the objects, as shown in getCommon()`:

interface Common {
    common: boolean;
}

interface A extends Common {
    a: A[];
}

interface B extends Common {
    b: B[];
}

interface C extends Common {
    c: C[];
}

type Container = {
    a: A[],
    b: B[],
    c: C[]
};

let item: Container = {
    a: [ { a: [], common: true } ],
    b: [ { b: [], common: true } ],
    c: [ { c: [], common: true } ]
};

type Key = 'a' | 'b' | 'c';

function getCommon (thisKey: Key) {
    return item[thisKey].map(a => a.common); // This line has an error
}

Typescript Playground link

However, Typescript 2.1 is giving me a compile error:

Cannot invoke an expression whose type lacks a call signature. 
Type '{ <U>(this: [A, A, A, A, A], callbackfn: (value: A, index: number, array: A[]) => U, 
thisArg?: an...' has no compatible call signatures.

Is this a bug/limitation in Typescript, or am I doing something wrong?

1

There are 1 answers

2
Paleo On

It seems it is a limitation. But you can help the compiler by given it the type of the array: (A | B | C)[].

function getCommon(thisKey: Key) {
    let arr: (A | B | C)[] = item[thisKey];
    return arr.map(a => a.common);
}