如何合并对象的通用列表?

时间:2018-08-15 19:15:49

标签: typescript

我想合并/合并任意数量的对象并保持类型安全。这是我到目前为止的内容:

func safeSetRegion(_ region: MKCoordinateRegion) {
    let myRegion = self.mapView.regionThatFits(region)
    if !(myRegion.span.latitudeDelta.isNaN || myRegion.span.longitudeDelta.isNaN) {

        // check for maximum span values (otherwise the setRegion(myRegion) call will crash)
        let deltaLat = min(180.0, myRegion.span.latitudeDelta)
        let deltaLong = min(360.0, myRegion.span.longitudeDelta)

        // now build a nice and easy span ...
        let coordinatesRegionWithSpan =  MKCoordinateSpan(
                     latitudeDelta: deltaLat,
                     longitudeDelta: deltaLong)

        // ... to use for an adjusted region
        let adjustedCoordinateRegion = MKCoordinateRegion(
            center: region.center,
            span: coordinatesRegionWithSpan)

        // and now it's safe to call
        self.mapView.setRegion(adjustedCoordinateRegion, animated: true)
    }
}

问题在于foobar的类型为function combine(...args) { return (<any>Object).assign({}, ...args); } const foobar = combine( { foo: 1 }, { bar: 2 } ); console.log(foobar); // {foo: 1, bar: 2} 。对于已知数量的参数,我可以得到类型安全,而不是任何参数。这是2个参数的解决方案:

any

我试图使function combine<T, U>(a: T, b: U): T & U { return (<any>Object).assign({}, a, b); } 正常工作,但是却无济于事。

注意:function combine<T extends any[]>(...args: T)可以解决(<any>Object)

1 个答案:

答案 0 :(得分:2)

您可以对conditional types使用技巧,以合并类型并获得这些类型的交集:

type UnionToIntersection<U> =
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

假设您使用的是TS 3.0,则应进行以下键入:

declare function combine<T extends any[]>(...args: T): UnionToIntersection<T[number]>;

让我们测试一下:

const foobar = combine(
  { foo: 1 },
  { bar: 2 }
);
// { foo: number } & { bar: number }

很好,我想。

希望有帮助。祝你好运!