Typescript 函数根据参数属性返回类型

时间:2021-01-29 09:24:33

标签: typescript function generics parameters

如何为函数创建正确的类型,以便根据其输入参数的属性,在调用此函数时获得正确的返回类型?

这是我目前得到的,但是当 boolean | boolean[] 应该给我 fn({ a: 42 })boolean 应该给我{时,两个调用都给我相同的 fn({ b: 'hi' }) 类型{1}}。

boolean[]

另外,我不是必须在类型中定义文字对象属性 type ParamType = { a?: number, b?: string } type ReturnType<T> = T extends 'a' ? boolean : T extends 'b' ? boolean[] : never[] function fn<T extends keyof ParamType>(arg: ParamType) { if (arg.a) { return true as ReturnType<T>; } else if (arg.b) { return [true, false] as ReturnType<T>; } else return [] as ReturnType<T>; } fn({ a: 42 }); // function fn<"a" | "b">(arg: ParamType ): boolean | boolean[] fn({ b: 'hi' }); // function fn<"a" | "b">(arg: ParamType ): boolean | boolean[] a 两次的忠实粉丝,如果有更好的方法来做到这一点,请指出我的正确方向。

1 个答案:

答案 0 :(得分:0)

您的问题很不寻常,但首先:使用 in 运算符检查密钥是否存在。其次:如果 a 和 b 都被声明,即使是可选的,这也不起作用。使用联合。最后,如果你声明了一个没有赋值给参数的类型参数,在大多数情况下,它是没有作用的。

试试这个:

type ParamType = {a: number | string;} | {b: number | string;};
type MyReturnType<T> =
    T extends 'a' ? boolean :
    T extends 'b' ? boolean[] :
    never[];

function fn<T extends ParamType>(arg: T) {
    if ("a" in arg) {
        return true as MyReturnType<keyof T>;
    }
    else if ("b" in arg) {
        return [true, false] as MyReturnType<keyof T>;
    }
    else return [] as MyReturnType<keyof T>;
}

fn({a: 42}); 
/*function fn<{
    a: number;
}>(arg: {
    a: number;
}): boolean*/
fn({b: 'hi'});
/*function fn<{
    b: string;
}>(arg: {
    b: string;
}): boolean[]*/

对于联合,请参见 https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#unions,对于 in 类型保护,请参见 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#type-guards-inferred-from-in-operator