Displayed below is the compiler error relating to the code snippet you provided:
function test <T extends Bar | Foo>(items: T[]): void {
console.log(items);
test2(items);
// ~~~~~
}
Argument of type 'T[]' cannot be assigned to a parameter of type 'Bar[] | Foo[]'.
Type 'T[]' is not compatible with type 'Bar[]'.
Type 'T' is not assignable to type 'Bar'.
Type 'Foo | Bar' cannot be assigned to type 'Bar'.
Type 'Foo' cannot be assigned to type 'Bar'.
Type 'T' is not assignable to type '{ date: Date; list: string; }'.
Type 'Foo | Bar' cannot be assigned to type '{ date: Date; list: string; }'.
Type 'string' cannot be assigned to type '{ date: Date; list: string; }'. (2345)
This means that currently, your test
function expects an array of values where each individual value can be either of type Foo or Bar. It allows for a mixed array containing elements of both types.
For example, this works fine:
TS Playground
const array = [
{ t: 'hello' },
'world',
{ date: new Date(), list: 'str' },
];
test(array); // no issues
However, your test2
function requires an array argument containing exclusively Foo elements or exclusively Bar elements:
function test2 (items: Bar[] | Foo[]): void;
Hence, when passing the same array to test2
, the error arises:
TS Playground
const array = [
{ t: 'hello' },
'world',
{ date: new Date(), list: 'str' },
];
test2(array);
// ~~~~~
// A very similar compiler error happens here
To resolve this, adjust the parameter of the test2
function to accept an array with mixed Foo and Bar elements, like so:
(Bar | Foo)[]
When combined, the updated functions will look like this:
TS Playground
type Foo = { t: string };
type Bar = string | {
date: Date;
list: string;
};
function test <T extends Bar | Foo>(items: T[]): void {
console.log(items);
test2(items); // no errors now
}
// function test2 (items: Bar[] | Foo[]) {
function test2 (items: (Bar | Foo)[]): void {
console.log(items);
}
Alternatively, if you prefer a stricter test
function that only accepts arrays with exclusively Foo or Bar elements, modify it as follows while maintaining compatibility with test2
:
TS Playground
function test <T extends Bar[] | Foo[]>(items: T): void {
console.log(items);
test2(items); // no issues
}