可选参数效果返回类型

时间:2019-11-23 14:52:20

标签: typescript

下面,我尝试使用一个带有可选参数B并有条件地处理返回值(无论是否传入)的函数。

export type SingleArgFunc = (arg: any) => any
export type SingleArgFuncs = { [k: string]: SingleArgFunc }

type Bextender<A> = (a: any) => any
type Cextender<A> = any
type Dextender<A, B, C> = B
// type Dextender<A, B, C> = B extends ????? : null : boolean

function Example<A extends SingleArgFuncs, B extends Bextender<A>>(a: A, b?: B) {
    return function Inner<C extends Cextender<B>>(c: C): Dextender<A, B, C> {
        return {} as Dextender<A, B, C>
    }
} 

const returnIs = Example({}) // const returnIs: <C extends any>(c: C) => Bextender<{}>
const returnIs2 = Example({}, () => 'meow') // const returnIs2: <C extends any>(c: C) => () => string

这似乎可以通过检查B的返回类型来实现,但是由于某种原因boolean | null,使其成为交集。

export type SingleArgFunc = (arg: any) => any
export type SingleArgFuncs = { [k: string]: SingleArgFunc }

type Bextender<A> = (a: any) => any
type Cextender<A> = any
type Dextender<A, B, C> = B extends SingleArgFunc ? ReturnType<B> extends Bextender<A> ? null : boolean : never

function Example<A extends SingleArgFuncs, B extends Bextender<A>>(a: A, b?: B) {
    return function Inner<C extends Cextender<B>>(c: C): Dextender<A, B, C> {
        return {} as Dextender<A, B, C>
    }
} 

const returnIs = Example({}) // const returnIs: <C extends any>(c: C) => boolean | null
const returnIs2 = Example({}, () => 'meow') // const returnIs2: <C extends any>(c: C) => boolean

如果未定义B,如何写条件返回。

1 个答案:

答案 0 :(得分:0)

我相信这可行:

export type SingleArgFunc = (arg: any) => any
export type SingleArgFuncs = { [k: string]: SingleArgFunc }

type CallbackAvailable<CbExt, Cb, IfA, NotA> = Cb extends SingleArgFunc ? CbExt extends ReturnType<Cb> ? IfA : NotA : never

type Bextender<A> = (a: any) => any
type Cextender<A> = any
type Dextender<A, B, C> = CallbackAvailable<Bextender<A>, B, null, true>

function Example<A extends SingleArgFuncs, B extends Bextender<A>>(a: A, b?: B) {
    return function Inner<C extends Cextender<B>>(c: C): Dextender<A, B, C> {
        return {} as Dextender<A, B, C>
    }
} 

const returnIs = Example({}) // const returnIs: <C extends any>(c: C) => boolean | null
const returnIs2 = Example({}, () => 'meow') // const returnIs2: <C extends any>(c: C) => boolean