reactjstypescriptgenericsconditional-types

custom type with conditional generic type gives ts error when used in useState


I have a type definition like so:

export type MutationResponse<T = never> = {
    status: number;
    message: string | null;
} & (T extends never ? {} : { data: T });

When i use it like so:

const [response, setResponse] = useState<MutationResponse>({ status: 0, message: "" });

I get the following error:

Object literal may only specify known properties, and 'status' does not exist in type '() => never'

Why is this and how do i fix this?

fyi, when i use it with the generic type parameter specified like so it works just totally fine:

const [response, setResponse] = useState<MutationResponse<string>>({ status: 0, message: "", data: "" });

Solution

  • The issue is the below code segment.

    ...
    & (T extends never ? {} : { data: T });
    

    Please observe the below test types. While Type2 is never, Type4 is {}. The reason is given below.

    type Type1<T> = T extends never ? {} : { data: T }
    
    type Type2 = Type1<never>;  // never
    
    type Type3<T> = [T] extends [never] ? {} : { data: T }
    
    type Type4 = Type3<never>; // {}
    

    Type1 is a distributive conditional type. Conditional types distribute over unions. never is the empty union (ie a union with no members). So when distributing over never, Type1 is never applied, since there are no members in this union and thus the result is never.

    In Type3, the distribution behaviour is disabled. Therefore it produces the desired result.

    Citation:

    Generic conditional type T extends never ? 'yes' : 'no' resolves to never when T is never.