Reputation: 2681
I'm having a lot of trouble understanding the intersection types. Here it is what I'm referring to:
type FooList = Foo[] & {
bar: string
};
interface Foo {
baz: string;
}
After a lot of fiddling I'm unable to create a typed array of FooList
.
These typings are not mine, they are from this library.
Does these types mean FooList
must be an array of Foo
s and also have an object bar
? Does each Foo
object has to contain a property bar
?
Here is the link to the playground
Upvotes: 5
Views: 6268
Reputation: 328758
A FooList
is both an array of Foo
objects, as well as an object that contains a string-valued bar
property.
If you're willing to use type assertions, it's easy enough to create one since you can just tell the compiler you know what you're doing:
var foos: any; // turn off type checking
foos = [{ baz: 'baz1' }, { baz: 'baz2' }];
foos.bar = 'bar';
var fooList: FooList = foos as FooList; // assert type of fooList
Creating one of these things safely, where the compiler guarantees that you've made something of the right type is a little tricky, but you can do it with Object.assign()
, which returns an intersection of its parameter types:
const fooList: FooList = Object.assign([{ baz: 'baz' }, { baz: 'baz' }], { bar: 'bar' });
Hope that helps. Good luck!
Please ignore the stuff below; I'm not sure what came over me, but spreading an array into an object is unlikely to work the way anyone wants, since Array
prototype methods will not be copied. Just use the above Object.assign()
solution.
@CésarAlberca said:
Thanks! Yours was my preferred solution. What is the equivalent of object assign using the spread operator?
Oh, sure, you could do that:
const fooList2: FooList = { ...[{ baz: 'baz' }, { baz: 'baz' }], ...{ bar: 'bar' } };
or
const fooList3: FooList = { ...[{ baz: 'baz' }, { baz: 'baz' }], bar: 'bar' };
Cheers.
Upvotes: 4
Reputation: 9
Look at my demo of usage.
type LinkedList<T> = T & { next: LinkedList<T> };
interface Person {
name: string;
}
var people: LinkedList<Person>;
var person: Person = { name: "Joey" };
var childPerson: Person = { name: "James" };
var grandChildPerson: Person = { name: "John" };
people = person;
people.next = childPerson;
people.next.next = grandChildPerson;
alert(JSON.stringify(people));
See typescript documentation of type aliases and intersection types
Upvotes: 0
Reputation: 164217
FooList
is an array with items of type Foo
which also has a string property named bar
.
Here's how you'd create it:
function createFooList(bar: string, ...items: Foo[]): FooList {
const arr = [] as FooList;
arr.bar = bar;
arr.push(...items);
return arr;
}
Or:
function createFooList(bar: string, ...items: Foo[]): FooList {
(items as FooList).bar = bar;
return items as FooList;
}
Upvotes: 1