简体   繁体   English

Typescript function 基于参数属性的返回类型

[英]Typescript function return type based on parameter properties

How can I create the proper typing for a function such that depending on the properties on its input parameters, I get the correct return type when calling this function?如何为 function 创建正确的类型,以便根据其输入参数的属性,在调用此 function 时获得正确的返回类型?

Here's what I've got at the moment but both calls are giving me the same boolean | boolean[]这是我目前得到的,但两个电话都给我相同的boolean | boolean[] boolean | boolean[] type when fn({ a: 42 }) should give me boolean and fn({ b: 'hi' }) should give me boolean[] . boolean | boolean[]fn({ a: 42 })应该给我booleanfn({ b: 'hi' })应该给我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[]

Also I'm not a huge fan of having to define the literal object properties a & b twice in the types, if there is a better way to do this please point me in the right direction.此外,我不太喜欢在类型中定义文字 object 属性ab两次,如果有更好的方法,请指出正确的方向。

Your problem is quite unusual but firstly: use in operator to check key existence.您的问题很不寻常,但首先:使用in operator 来检查密钥是否存在。 Secondly: this has no effect if both a and b are declared, even if optional.其次:如果 a 和 b 都被声明,这没有效果,即使是可选的。 Use union.使用联合。 And finally, if you declare type parameter which is not assigned to a parameter, in most cases, it has no effect.最后,如果你声明了一个没有赋值给参数的类型参数,在大多数情况下,它是没有效果的。

Try this:试试这个:

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[]*/

See https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#unions for unions, and https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#type-guards-inferred-from-in-operator for in type guard.请参阅https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#unionshttps://www.typescriptlang.org/docs/handbook/release-notes/类型保护的 typescript-2-7.html#type-guards-inferred-from-in-operator in

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

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