简体   繁体   中英

why TypeScript condition type can't work correctly for optional parameter?

i want to know wheather function's first args is optional, so i write this:

type F1 = (payload?: number) => null;
type Res1 = F1 extends (a?: any) => any ? 1 : 2; // got 1
type Res2 = F1 extends (a: any) => any ? 1 : 2; // got 1, but 2 expected

type F2 = (payload: number) => null;
type Res3 = F2 extends (a?: any) => any ? 1 : 2; // got 1, but 2 expected
type Res4 = F2 extends (a: any) => any ? 1 : 2; // got 1

ALL OF THEM are both equl to 1 , why? and how do i do?

You can read 'extends' as 'is assignable to'.

type F1 = (payload?: number) => null;
type Res2 = F1 extends (a: any) => any ? 1 : 2; // got 1, but 2 expected

Is (payload?: number) => null assignable to (a: any) => any ? Let's check:

// Works
const res2: (a: any) => any = (payload?: number) => null;

(a: any) => any accepts any value for a , including undefined or a number as specified by payload, so we can see that (payload?: number) => null is assignable and therefore F1 extends (a: any) => any should evaluate to true and return 1.

Instead, you can make the arguments of your function to test optional using Partial, and check if the resulting arguments are assignable to the original arguments:


type ArgumentType<F extends (...args: any) => any> = F extends (...args: infer A) => any ? A : never;

type FirstArgumentOptional<F extends (...args: any) => any> =
    Partial<ArgumentType<F>> extends ArgumentType<F>
        ? true 
        : false


type T1 = FirstArgumentOptional<(a: any) => any>; // false
type T2 = FirstArgumentOptional<(a?: any) => any>; // true
type T3 = FirstArgumentOptional<() => any>; // true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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