繁体   English   中英

Typescript 中的 Generics:在函数中传递 generics

[英]Generics in Typescript: Passing generics in Functions

我的 typescript 代码如下:(在 typescript 4.4 内)

export function convert<T extends (...args: any[]) => any>(
    func: T
): (_this: ThisParameterType<T>, ...args: OmitThisParameter<Parameters<T>>) => ReturnType<T> {
    return Function.call.bind(
        Function.bind,
        Function.call
    )(func) as (_this: ThisParameterType<T>, ...args: OmitThisParameter<Parameters<T>>) => ReturnType<T>;
}

但是当我像这样使用它时:

// mark 1
const arrayShift = convert([].shift);
// expect: const shifted: string
const shifted = arrayShift(["1"]); // const shifted: undefined

// mark 2
const arrayMap = convert([].map);
// expect (parameter) e: string
arrayMap(["1"], (e) => { // (parameter) e: never
    return parseInt(e, 10);
});

如何通过修改名为“convert”的 function 获得预期类型?

我设法通过两步法实现了它。 convert返回一个 function,你可以调用它,有或没有 arguments。

看操场

function convert<A extends Array<T>, T extends any, K extends keyof Array<T>>(
  array: A extends Array<infer U> ? Array<U> : Array<T>,
  key: K,
) {
  function convertArray<A extends Array<T>, T extends any>(
    array: A extends Array<infer U> ? Array<U> : Array<T>,
    key: K,
  ) {
    return array[key]
  }
  return function<S extends Array<Y>, Y extends any>(
    subjectedArray: S extends Array<infer SK> ? Array<SK> : Array<Y>,
    args?: any[] // not yet figured out to call convertArray with args and keep types
  ) {
    return (convertArray<S, Y>(
      subjectedArray,
      key
    ))
  }
}

const arrayShift = convert([], 'shift')
const arrayMap = convert([], 'map')

const empty = arrayShift([])() // const empty: undefined
const shifted = arrayShift(["123"])() // const shifted: string | undefined
const mapped = arrayMap(["1"])(e => { // (parameter) e: string
  return parseInt(e, 10);
}) // const mapped: number[]

type Car = {
  engine: 'petrol' | 'gasoline'
}
const cars: Car[] = []
const emptyCars = arrayShift(cars)() // const emptyCars: Car | undefined

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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