【问题标题】:Keep type parameter when calling generic function in TypeScript在 TypeScript 中调用泛型函数时保留类型参数
【发布时间】:2023-01-12 19:46:24
【问题描述】:

假设如下:

type GenericFunc<T> = () => Promise<T>

interface FuncWithModifier<T> extends GenericFunc<T> {
  modifier: GenericFunc<T>
}

const wrapFunction = <T> (func: GenericFunc<T>): FuncWithModifier<T> => {
    const modifier: GenericFunc<T> = async () => func()
    return Object.assign(func, { modifier })
}

现在我可以创建带有修饰符的函数,如下所示:

const stringFunc: FuncWithModifier<string> = wrapFunction(async () => 'foo')
const str1: string = await stringFunc()
const str2: string = await stringFunc.modifier()

它也可以在没有显式类型注释的情况下工作:

const implicitStringFunc = wrapFunction(async () => 'foo')
const str3: string = await implicitStringFunc()
const str4: string = await implicitStringFunc.modifier()

我现在想要的是一个通用函数,例如就像是:

// doesn't work, invalid syntax!
const genericFunc = <T = unknown> wrapFunction(async () => null as any)
const num1: number = await genericFunc<number>()
const num2: number = await genericFunc.modifier<number>()
const bool1: boolean = await genericFunc<boolean>()
const bool2: boolean = await genericFunc.modifier<boolean>()

但是,似乎无法保留被调用函数(上面的wrapFunction)的类型参数,而是将其应用于结果。还有另一种方法可以实现这一目标吗?

TS Playground

【问题讨论】:

  • 您可以从 wrapFunction 参数推断返回类型。不知道为什么你需要额外的通用。但是,如果你需要,你可以尝试this,但它只适用于any. I just not sure whether you want to use any or not

标签: typescript generics


【解决方案1】:

考虑这个例子:


type FuncWithModifier<T> = {
    <R = 'unset'>(): R extends 'unset' ? Promise<T> : Promise<R>
    modifier: <R = 'unset'>() => R extends 'unset' ? Promise<T> : Promise<R>
}

function wrapFunction<R,>(func: () => Promise<R>): FuncWithModifier<R>
function wrapFunction<R,>(func: () => Promise<R>) {
    const modifier = async () => func()
    return Object.assign(func, { modifier })
}


const stringFunc: FuncWithModifier<string> = wrapFunction(async () => 'foo')
const str1 = await stringFunc()
const str2 = await stringFunc.modifier()

const implicitStringFunc = wrapFunction(async () => 2)
const str3 = await implicitStringFunc()
const str4 = await implicitStringFunc.modifier()



const genericFunc = wrapFunction(async () => 42)
const num1 = await genericFunc<number>()
const num2 = await genericFunc.modifier<number>()
const bool1 = await genericFunc<boolean>()
const bool2 = await genericFunc.modifier<boolean>()

Playground

我已经使用unset 默认值来检查是否提供了泛型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2021-06-12
    • 2016-11-01
    • 2020-11-10
    • 2019-09-19
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多