4 ms·
Looking at the type definition, it is expecting the same type: /**
by funkaster 8y ago
Looking at the type definition, it is expecting the same type:
/**
* Combines two or more arrays.
* @param items Additional items to add to the end of array1.
*/
concat(...items: ConcatArray<T>[]): T[];
/**
* Combines two or more arrays.
* @param items Additional items to add to the end of array1.
*/
concat(...items: (T | ConcatArray<T>)[]): T[];
- dunham 8y agoThat's typescript's type definition. Flow recognizes that concat returns a new array, so it specifies that calling concat on an Array<T> with an Array<S> as an argument returns an Array<T|S>. Their actual definition is: declare class $ReadOnlyArray<+T> { // concat creates a new array concat<S, Item: $ReadOnlyArray<S> | S>(...items: Array<Item>): Array<T | S>; Personally, I'm ok with that and think it is useful. Although the return value could be an array of any type more general than T|S and the types of the argument arrays could vary. (i.e. Array<T>.concat(Array<S1>,Array<S2>,...): Array<? extends (T|S1|S2)>) but I don't know if that can be expressed in flow. I don't think either gets it perfect, but flow is trying to at least capture the fact that the return value can't be an array of a type that is disjoint from T|S. In practice, I've been impressed by the level of detail of information that is captured and propagated by flow's type checker.