简体   繁体   中英

In flow how to accept a heterogeneous array, and return that array

When I have a function which accepts an array of a generic type and return a transformed array, I could write:

function myfun<T>(input: Array<T>): Array<T> {}

However this fails if the array is of heterogeneous type, since T is then different over the array. Now since I know that T will always be a subtype of a certain base: BaseTy and during the function I only use functions from/that operate on the base type, I could write:

function myfun(input: Array<BaseTy>): Array<BaseTy> {}

However this has the problem that the actual type is "lost" and the array is thus no longer a heterogeneous array of the derived type.

Can this be fixed in flow without resorting to unsafe typecasts or any ?

You'll want to use a bounded generic to specify the minimum type that can be accepted, while also allowing the function to return a more specific type:

function myfun<T: BaseTy>(input: Array<T>): Array<T> {
    // whatever you want to do here
    return input
}

Full code example:

type BaseType = {
    base: 'whatever'
}
type TypeA = BaseType & { a: 'Foo' }
type TypeB = BaseType & { b: 'Bar' }
type TypeC = BaseType & { c: 'Baz' }

function myfun<T: BaseType>(input: Array<T>): Array<T> {
    return input
}

const a = {
  base: 'whatever',
  a: 'Foo'
}

const b = {
  base: 'whatever',
  b: 'Bar'
}

const c = {
  base: 'whatever',
  c: 'Baz'
}


const aAndBs: Array<TypeA | TypeB> = [a, b]
const aAndCs: Array<TypeA | TypeC> = [a, c]

// Correct
const xs1: Array<TypeA | TypeB> = myfun(aAndBs)

// Error - It's actually returning Array<TypeA | TypeC>
const xs2: Array<TypeA | TypeB> = myfun(aAndCs)

( Try )

Like Jordan said, you may want to change the type of the input array to $ReadOnlyArray if you run into trouble with variance :

function myfun<T: BaseType>(input: $ReadOnlyArray<T>): $ReadOnlyArray<T> {
    return input
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM